Merge branch 'master' into addTsConfigWatcher

This commit is contained in:
zhengbli
2015-08-19 12:44:29 -07:00
parent 58ac077a49
commit 42942a5dc4
986 changed files with 26180 additions and 10749 deletions
+13 -11
View File
@@ -17,7 +17,7 @@ var docDirectory = "doc/";
var builtDirectory = "built/";
var builtLocalDirectory = "built/local/";
var LKGDirectory = "bin/";
var LKGDirectory = "lib/";
var copyright = "CopyrightNotice.txt";
var thirdParty = "ThirdPartyNoticeText.txt";
@@ -141,7 +141,9 @@ var harnessSources = harnessCoreSources.concat([
"session.ts",
"versionCache.ts",
"convertToBase64.ts",
"transpile.ts"
"transpile.ts",
"reuseProgramStructure.ts",
"cachingInServerLSHost.ts"
].map(function (f) {
return path.join(unittestsDirectory, f);
})).concat([
@@ -218,7 +220,7 @@ var compilerFilename = "tsc.js";
function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, noOutFile, generateDeclarations, outDir, preserveConstEnums, keepComments, noResolve, stripInternal, callback) {
file(outFile, prereqs, function() {
var dir = useBuiltCompiler ? builtLocalDirectory : LKGDirectory;
var options = "--module commonjs -noImplicitAny";
var options = "--module commonjs --noImplicitAny --noEmitOnError";
// Keep comments when specifically requested
// or when in debug mode.
@@ -339,10 +341,10 @@ file(diagnosticInfoMapTs, [processDiagnosticMessagesJs, diagnosticMessagesJson],
complete();
});
ex.run();
}, {async: true});
}, {async: true});
desc("Generates a diagnostic file in TypeScript based on an input JSON file");
task("generate-diagnostics", [diagnosticInfoMapTs]);
task("generate-diagnostics", [diagnosticInfoMapTs]);
// Publish nightly
@@ -479,11 +481,11 @@ file(specMd, [word2mdJs, specWord], function () {
child_process.exec(cmd, function () {
complete();
});
}, {async: true});
}, {async: true});
desc("Generates a Markdown version of the Language Specification");
task("generate-spec", [specMd]);
task("generate-spec", [specMd]);
// Makes a new LKG. This target does not build anything, but errors if not all the outputs are present in the built/local directory
@@ -615,7 +617,7 @@ task("runtests", ["tests", builtLocalDirectory], function() {
exec(cmd, deleteTemporaryProjectOutput);
}, {async: true});
desc("Generates code coverage data via instanbul");
desc("Generates code coverage data via instanbul");
task("generate-code-coverage", ["tests", builtLocalDirectory], function () {
var cmd = 'istanbul cover node_modules/mocha/bin/_mocha -- -R min -t ' + testTimeout + ' ' + run;
console.log(cmd);
@@ -658,7 +660,7 @@ task("runtests-browser", ["tests", "browserify", builtLocalDirectory], function(
function getDiffTool() {
var program = process.env['DIFF']
if (!program) {
fail("Add the 'DIFF' environment variable to the path of the program you want to use.");
fail("Add the 'DIFF' environment variable to the path of the program you want to use.");
}
return program;
}
@@ -667,14 +669,14 @@ function getDiffTool() {
desc("Diffs the compiler baselines using the diff tool specified by the 'DIFF' environment variable");
task('diff', function () {
var cmd = '"' + getDiffTool() + '" ' + refBaseline + ' ' + localBaseline;
console.log(cmd);
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 = '"' + getDiffTool() + '" ' + refRwcBaseline + ' ' + localRwcBaseline;
console.log(cmd);
console.log(cmd);
exec(cmd);
}, {async: true});
+1 -1
View File
@@ -1,2 +1,2 @@
#!/usr/bin/env node
require('./tsc.js')
require('../lib/tsc.js')
+1 -1
View File
@@ -1,2 +1,2 @@
#!/usr/bin/env node
require('./tsserver.js')
require('../lib/tsserver.js')
Binary file not shown.
Binary file not shown.
+1720 -1192
View File
File diff suppressed because it is too large Load Diff
View File
View File
View File
View File
View File
View File
View File
View File
View File
@@ -1450,6 +1450,7 @@ declare namespace ts {
function getTrailingCommentRanges(text: string, pos: number): CommentRange[];
function isIdentifierStart(ch: number, languageVersion: ScriptTarget): boolean;
function isIdentifierPart(ch: number, languageVersion: ScriptTarget): boolean;
function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean, languageVariant: ts.LanguageVariant, text?: string, onError?: ErrorCallback, start?: number, length?: number): Scanner;
}
declare namespace ts {
function getDefaultLibFileName(options: CompilerOptions): string;
+14 -4
View File
@@ -19,8 +19,7 @@
"type": "git",
"url": "https://github.com/Microsoft/TypeScript.git"
},
"preferGlobal": true,
"main": "./bin/typescript.js",
"main": "./lib/typescript.js",
"bin": {
"tsc": "./bin/tsc",
"tsserver": "./bin/tsserver"
@@ -38,6 +37,17 @@
"tslint": "latest"
},
"scripts": {
"test": "jake runtests"
}
"pretest": "jake tests",
"test": "jake runtests",
"build": "npm run build:compiler && npm run build:tests",
"build:compiler": "jake local",
"build:tests": "jake tests",
"clean": "jake clean"
},
"browser": {
"buffer": false,
"fs": false,
"os": false,
"path": false
}
}
+29 -6
View File
@@ -1,8 +1,16 @@
// word2md - Word to Markdown conversion tool
//
// word2md converts a Microsoft Word document to Markdown formatted text. The tool uses the
// Word Automation APIs to start an instance of Word and access the contents of the document
// being converted. The tool must be run using the cscript.exe script host and requires Word
// to be installed on the target machine. The name of the document to convert must be specified
// as a command line argument and the resulting Markdown is written to standard output. The
// tool recognizes the specific Word styles used in the TypeScript Language Specification.
var sys = (function () {
var fileStream = new ActiveXObject("ADODB.Stream");
fileStream.Type = 2;
fileStream.Type = 2 /*text*/;
var binaryStream = new ActiveXObject("ADODB.Stream");
binaryStream.Type = 1;
binaryStream.Type = 1 /*binary*/;
var args = [];
for (var i = 0; i < WScript.Arguments.length; i++) {
args[i] = WScript.Arguments.Item(i);
@@ -17,11 +25,13 @@ var sys = (function () {
fileStream.Open();
binaryStream.Open();
try {
// Write characters in UTF-8 encoding
fileStream.Charset = "utf-8";
fileStream.WriteText(data);
// We don't want the BOM, skip it by setting the starting location to 3 (size of BOM).
fileStream.Position = 3;
fileStream.CopyTo(binaryStream);
binaryStream.SaveToFile(fileName, 2);
binaryStream.SaveToFile(fileName, 2 /*overwrite*/);
}
finally {
binaryStream.Close();
@@ -59,6 +69,17 @@ function convertDocumentToMarkdown(doc) {
setProperties(replace, replaceOptions);
find.execute(findText, false, false, false, false, false, true, 0, true, replaceText, 2);
}
function fixHyperlinks() {
var count = doc.hyperlinks.count;
for (var i = 0; i < count; i++) {
var hyperlink = doc.hyperlinks.item(i + 1);
var address = hyperlink.address;
if (address && address.length > 0) {
var textToDisplay = hyperlink.textToDisplay;
hyperlink.textToDisplay = "[" + textToDisplay + "](" + address + ")";
}
}
}
function write(s) {
result += s;
}
@@ -184,14 +205,15 @@ function convertDocumentToMarkdown(doc) {
findReplace("&lt;", { style: "Code Fragment" }, "<", {});
findReplace("&lt;", { style: "Terminal" }, "<", {});
findReplace("", { font: { subscript: true } }, "<sub>^&</sub>", { font: { subscript: false } });
findReplace("", { style: "Code Fragment" }, "`^&`", { style: -66 });
findReplace("", { style: "Production" }, "*^&*", { style: -66 });
findReplace("", { style: "Terminal" }, "`^&`", { style: -66 });
findReplace("", { style: "Code Fragment" }, "`^&`", { style: -66 /* default font */ });
findReplace("", { style: "Production" }, "*^&*", { style: -66 /* default font */ });
findReplace("", { style: "Terminal" }, "`^&`", { style: -66 /* default font */ });
findReplace("", { font: { bold: true, italic: true } }, "***^&***", { font: { bold: false, italic: false } });
findReplace("", { font: { italic: true } }, "*^&*", { font: { italic: false } });
doc.fields.toggleShowCodes();
findReplace("^19 REF", {}, "[^&](#^&)", {});
doc.fields.toggleShowCodes();
fixHyperlinks();
writeDocument();
result = result.replace(/\x85/g, "\u2026");
result = result.replace(/\x96/g, "\u2013");
@@ -210,3 +232,4 @@ function main(args) {
app.quit();
}
main(sys.args);
//# sourceMappingURL=file:///c:/ts/scripts/word2md.js.map
+24
View File
@@ -100,9 +100,19 @@ module Word {
toggleShowCodes(): void;
}
export interface Hyperlink {
address: string;
textToDisplay: string;
range: Range;
}
export interface Hyperlinks extends Collection<Hyperlink> {
}
export interface Document {
fields: Fields;
paragraphs: Paragraphs;
hyperlinks: Hyperlinks;
builtInDocumentProperties: Collection<any>;
close(saveChanges: boolean): void;
range(): Range;
@@ -195,6 +205,18 @@ function convertDocumentToMarkdown(doc: Word.Document): string {
find.execute(findText, false, false, false, false, false, true, 0, true, replaceText, 2);
}
function fixHyperlinks() {
var count = doc.hyperlinks.count;
for (var i = 0; i < count; i++) {
var hyperlink = doc.hyperlinks.item(i + 1);
var address = hyperlink.address;
if (address && address.length > 0) {
var textToDisplay = hyperlink.textToDisplay;
hyperlink.textToDisplay = "[" + textToDisplay + "](" + address + ")";
}
}
}
function write(s: string) {
result += s;
}
@@ -347,6 +369,8 @@ function convertDocumentToMarkdown(doc: Word.Document): string {
findReplace("^19 REF", {}, "[^&](#^&)", {});
doc.fields.toggleShowCodes();
fixHyperlinks();
writeDocument();
result = result.replace(/\x85/g, "\u2026");
+5 -5
View File
@@ -74,7 +74,7 @@ namespace ts {
// If the current node is a container that also container that also contains locals. Examples:
//
// Functions, Methods, Modules, Source-files.
IsContainerWithLocals = IsContainer | HasLocals
IsContainerWithLocals = IsContainer | HasLocals
}
export function bindSourceFile(file: SourceFile) {
@@ -139,7 +139,7 @@ namespace ts {
function getDeclarationName(node: Declaration): string {
if (node.name) {
if (node.kind === SyntaxKind.ModuleDeclaration && node.name.kind === SyntaxKind.StringLiteral) {
return '"' + (<LiteralExpression>node.name).text + '"';
return `"${(<LiteralExpression>node.name).text}"`;
}
if (node.name.kind === SyntaxKind.ComputedPropertyName) {
let nameExpression = (<ComputedPropertyName>node.name).expression;
@@ -830,7 +830,7 @@ namespace ts {
// Note: the node text must be exactly "use strict" or 'use strict'. It is not ok for the
// string to contain unicode escapes (as per ES5).
return nodeText === '"use strict"' || nodeText === "'use strict'";
return nodeText === "\"use strict\"" || nodeText === "'use strict'";
}
function bindWorker(node: Node) {
@@ -930,7 +930,7 @@ namespace ts {
function bindSourceFileIfExternalModule() {
setExportContextFlag(file);
if (isExternalModule(file)) {
bindAnonymousDeclaration(file, SymbolFlags.ValueModule, '"' + removeFileExtension(file.fileName) + '"');
bindAnonymousDeclaration(file, SymbolFlags.ValueModule, `"${removeFileExtension(file.fileName)}"`);
}
}
@@ -1062,4 +1062,4 @@ namespace ts {
: declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
}
}
}
}
+533 -374
View File
File diff suppressed because it is too large Load Diff
+5 -2
View File
@@ -335,7 +335,7 @@ namespace ts {
* @param fileName The path to the config file
*/
export function readConfigFile(fileName: string): { config?: any; error?: Diagnostic } {
let text = '';
let text = "";
try {
text = sys.readFile(fileName);
}
@@ -422,10 +422,13 @@ namespace ts {
if (json["files"] instanceof Array) {
fileNames = map(<string[]>json["files"], s => combinePaths(basePath, s));
}
else {
errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "files", "Array"));
}
}
else {
let exclude = json["exclude"] instanceof Array ? map(<string[]>json["exclude"], normalizeSlashes) : undefined;
let sysFiles = host.readDirectory(basePath, ".ts", exclude).concat(host.readDirectory(basePath, ".tsx", exclude));
let sysFiles = host.readDirectory(basePath, ".ts", exclude).concat(host.readDirectory(basePath, ".tsx", exclude));
for (let i = 0; i < sysFiles.length; i++) {
let name = sysFiles[i];
if (fileExtensionIs(name, ".d.ts")) {
+20 -8
View File
@@ -24,6 +24,7 @@ namespace ts {
set,
contains,
remove,
clear,
forEachValue: forEachValueInMap
};
@@ -51,6 +52,10 @@ namespace ts {
function normalizeKey(key: string) {
return getCanonicalFileName(normalizeSlashes(key));
}
function clear() {
files = {};
}
}
export const enum Comparison {
@@ -193,6 +198,13 @@ namespace ts {
return array[array.length - 1];
}
/**
* Performs a binary search, finding the index at which 'value' occurs in 'array'.
* If no such index is found, returns the 2's-complement of first index at which
* number[index] exceeds number.
* @param array A sorted array whose first element must be no larger than number
* @param number The value to be searched for in the array.
*/
export function binarySearch(array: number[], value: number): number {
let low = 0;
let high = array.length - 1;
@@ -219,10 +231,10 @@ namespace ts {
export function reduceLeft<T, U>(array: T[], f: (a: U, x: T) => U, initial: U): U;
export function reduceLeft<T, U>(array: T[], f: (a: U, x: T) => U, initial?: U): U {
if (array) {
var count = array.length;
const count = array.length;
if (count > 0) {
var pos = 0;
var result = arguments.length <= 2 ? array[pos++] : initial;
let pos = 0;
let result = arguments.length <= 2 ? array[pos++] : initial;
while (pos < count) {
result = f(<U>result, array[pos++]);
}
@@ -236,9 +248,9 @@ namespace ts {
export function reduceRight<T, U>(array: T[], f: (a: U, x: T) => U, initial: U): U;
export function reduceRight<T, U>(array: T[], f: (a: U, x: T) => U, initial?: U): U {
if (array) {
var pos = array.length - 1;
let pos = array.length - 1;
if (pos >= 0) {
var result = arguments.length <= 2 ? array[pos--] : initial;
let result = arguments.length <= 2 ? array[pos--] : initial;
while (pos >= 0) {
result = f(<U>result, array[pos--]);
}
@@ -523,7 +535,7 @@ namespace ts {
if (path.lastIndexOf("file:///", 0) === 0) {
return "file:///".length;
}
let idx = path.indexOf('://');
let idx = path.indexOf("://");
if (idx !== -1) {
return idx + "://".length;
}
@@ -709,7 +721,7 @@ namespace ts {
/**
* List of supported extensions in order of file resolution precedence.
*/
export const supportedExtensions = [".tsx", ".ts", ".d.ts"];
export const supportedExtensions = [".ts", ".tsx", ".d.ts"];
const extensionsToRemove = [".d.ts", ".ts", ".js", ".tsx", ".jsx"];
export function removeFileExtension(path: string): string {
@@ -805,4 +817,4 @@ namespace ts {
Debug.assert(false, message);
}
}
}
}
+6 -5
View File
@@ -750,14 +750,18 @@ namespace ts {
}
function writeTypeAliasDeclaration(node: TypeAliasDeclaration) {
let prevEnclosingDeclaration = enclosingDeclaration;
enclosingDeclaration = node;
emitJsDocComments(node);
emitModuleElementDeclarationFlags(node);
write("type ");
writeTextOfNode(currentSourceFile, node.name);
emitTypeParameters(node.typeParameters);
write(" = ");
emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.type, getTypeAliasDeclarationVisibilityError);
write(";");
writeLine();
enclosingDeclaration = prevEnclosingDeclaration;
function getTypeAliasDeclarationVisibilityError(symbolAccesibilityResult: SymbolAccessiblityResult): SymbolAccessibilityDiagnostic {
return {
@@ -1371,7 +1375,7 @@ namespace ts {
else {
writeTextOfNode(currentSourceFile, node.name);
}
if (node.initializer || hasQuestionToken(node)) {
if (resolver.isOptionalParameter(node)) {
write("?");
}
decreaseIndent();
@@ -1497,11 +1501,8 @@ namespace ts {
// emit : declare function foo({y: [a, b, c]}: { y: [any, any, any] }) void;
writeTextOfNode(currentSourceFile, bindingElement.propertyName);
write(": ");
// If bindingElement has propertyName property, then its name must be another bindingPattern of SyntaxKind.ObjectBindingPattern
emitBindingPattern(<BindingPattern>bindingElement.name);
}
else if (bindingElement.name) {
if (bindingElement.name) {
if (isBindingPattern(bindingElement.name)) {
// If it is a nested binding pattern, we will recursively descend into each element and emit each one separately.
// In the case of rest element, we will omit rest element.
@@ -294,7 +294,7 @@ namespace ts {
Multiple_constructor_implementations_are_not_allowed: { code: 2392, category: DiagnosticCategory.Error, key: "Multiple constructor implementations are not allowed." },
Duplicate_function_implementation: { code: 2393, category: DiagnosticCategory.Error, key: "Duplicate function implementation." },
Overload_signature_is_not_compatible_with_function_implementation: { code: 2394, category: DiagnosticCategory.Error, key: "Overload signature is not compatible with function implementation." },
Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local: { code: 2395, category: DiagnosticCategory.Error, key: "Individual declarations in merged declaration {0} must be all exported or all local." },
Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local: { code: 2395, category: DiagnosticCategory.Error, key: "Individual declarations in merged declaration '{0}' must be all exported or all local." },
Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters: { code: 2396, category: DiagnosticCategory.Error, key: "Duplicate identifier 'arguments'. Compiler uses 'arguments' to initialize rest parameters." },
Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference: { code: 2399, category: DiagnosticCategory.Error, key: "Duplicate identifier '_this'. Compiler uses variable declaration '_this' to capture 'this' reference." },
Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference: { code: 2400, category: DiagnosticCategory.Error, key: "Expression resolves to variable declaration '_this' that compiler uses to capture 'this' reference." },
@@ -425,6 +425,8 @@ namespace ts {
JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property: { code: 2607, category: DiagnosticCategory.Error, key: "JSX element class does not support attributes because it does not have a '{0}' property" },
The_global_type_JSX_0_may_not_have_more_than_one_property: { code: 2608, category: DiagnosticCategory.Error, key: "The global type 'JSX.{0}' may not have more than one property" },
Cannot_emit_namespaced_JSX_elements_in_React: { code: 2650, category: DiagnosticCategory.Error, key: "Cannot emit namespaced JSX elements in React" },
A_member_initializer_in_a_const_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_const_enums: { code: 2651, category: DiagnosticCategory.Error, key: "A member initializer in a 'const' enum declaration cannot reference members declared after it, including members defined in other 'const' enums." },
Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration_instead: { code: 2652, category: DiagnosticCategory.Error, key: "Merged declaration '{0}' cannot include a default export declaration. Consider adding a separate 'export default {0}' declaration instead." },
Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." },
Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." },
Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported interface has or is using private name '{1}'." },
@@ -613,5 +615,6 @@ namespace ts {
Expected_corresponding_JSX_closing_tag_for_0: { code: 17002, category: DiagnosticCategory.Error, key: "Expected corresponding JSX closing tag for '{0}'." },
JSX_attribute_expected: { code: 17003, category: DiagnosticCategory.Error, key: "JSX attribute expected." },
Cannot_use_JSX_unless_the_jsx_flag_is_provided: { code: 17004, category: DiagnosticCategory.Error, key: "Cannot use JSX unless the '--jsx' flag is provided." },
A_constructor_cannot_contain_a_super_call_when_its_class_extends_null: { code: 17005, category: DiagnosticCategory.Error, key: "A constructor cannot contain a 'super' call when its class extends 'null'" },
};
}
+14 -2
View File
@@ -1,4 +1,4 @@
{
{
"Unterminated string literal.": {
"category": "Error",
"code": 1002
@@ -1165,7 +1165,7 @@
"category": "Error",
"code": 2394
},
"Individual declarations in merged declaration {0} must be all exported or all local.": {
"Individual declarations in merged declaration '{0}' must be all exported or all local.": {
"category": "Error",
"code": 2395
},
@@ -1689,6 +1689,14 @@
"category": "Error",
"code": 2650
},
"A member initializer in a 'const' enum declaration cannot reference members declared after it, including members defined in other 'const' enums.": {
"category": "Error",
"code": 2651
},
"Merged declaration '{0}' cannot include a default export declaration. Consider adding a separate 'export default {0}' declaration instead.": {
"category": "Error",
"code": 2652
},
"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",
"code": 4000
@@ -2445,5 +2453,9 @@
"Cannot use JSX unless the '--jsx' flag is provided.": {
"category": "Error",
"code": 17004
},
"A constructor cannot contain a 'super' call when its class extends 'null'": {
"category": "Error",
"code": 17005
}
}
+369 -222
View File
File diff suppressed because it is too large Load Diff
+48 -20
View File
@@ -844,6 +844,10 @@ namespace ts {
return token = scanner.scanJsxIdentifier();
}
function scanJsxText(): SyntaxKind {
return token = scanner.scanJsxToken();
}
function speculationHelper<T>(callback: () => T, isLookAhead: boolean): T {
// Keep track of the state we'll need to rollback to if lookahead fails (or if the
// caller asked us to always reset our state).
@@ -913,9 +917,11 @@ namespace ts {
return token > SyntaxKind.LastReservedWord;
}
function parseExpected(kind: SyntaxKind, diagnosticMessage?: DiagnosticMessage): boolean {
function parseExpected(kind: SyntaxKind, diagnosticMessage?: DiagnosticMessage, shouldAdvance = true): boolean {
if (token === kind) {
nextToken();
if (shouldAdvance) {
nextToken();
}
return true;
}
@@ -3148,7 +3154,7 @@ namespace ts {
}
function parseAwaitExpression() {
var node = <AwaitExpression>createNode(SyntaxKind.AwaitExpression);
const node = <AwaitExpression>createNode(SyntaxKind.AwaitExpression);
nextToken();
node.expression = parseUnaryExpressionOrHigher();
return finishNode(node);
@@ -3178,7 +3184,7 @@ namespace ts {
return parseTypeAssertion();
}
if (lookAhead(nextTokenIsIdentifierOrKeyword)) {
return parseJsxElementOrSelfClosingElement();
return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ true);
}
// Fall through
default:
@@ -3308,14 +3314,14 @@ namespace ts {
return finishNode(node);
}
function parseJsxElementOrSelfClosingElement(): JsxElement|JsxSelfClosingElement {
let opening = parseJsxOpeningOrSelfClosingElement();
function parseJsxElementOrSelfClosingElement(inExpressionContext: boolean): JsxElement | JsxSelfClosingElement {
let opening = parseJsxOpeningOrSelfClosingElement(inExpressionContext);
if (opening.kind === SyntaxKind.JsxOpeningElement) {
let node = <JsxElement>createNode(SyntaxKind.JsxElement, opening.pos);
node.openingElement = opening;
node.children = parseJsxChildren(node.openingElement.tagName);
node.closingElement = parseJsxClosingElement();
node.closingElement = parseJsxClosingElement(inExpressionContext);
return finishNode(node);
}
else {
@@ -3336,11 +3342,11 @@ namespace ts {
case SyntaxKind.JsxText:
return parseJsxText();
case SyntaxKind.OpenBraceToken:
return parseJsxExpression();
return parseJsxExpression(/*inExpressionContext*/ false);
case SyntaxKind.LessThanToken:
return parseJsxElementOrSelfClosingElement();
return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ false);
}
Debug.fail('Unknown JSX child kind ' + token);
Debug.fail("Unknown JSX child kind " + token);
}
function parseJsxChildren(openingTagName: EntityName): NodeArray<JsxChild> {
@@ -3368,7 +3374,7 @@ namespace ts {
return result;
}
function parseJsxOpeningOrSelfClosingElement(): JsxOpeningElement|JsxSelfClosingElement {
function parseJsxOpeningOrSelfClosingElement(inExpressionContext: boolean): JsxOpeningElement|JsxSelfClosingElement {
let fullStart = scanner.getStartPos();
parseExpected(SyntaxKind.LessThanToken);
@@ -3378,12 +3384,22 @@ namespace ts {
let attributes = parseList(ParsingContext.JsxAttributes, parseJsxAttribute);
let node: JsxOpeningLikeElement;
if (parseOptional(SyntaxKind.GreaterThanToken)) {
if (token === SyntaxKind.GreaterThanToken) {
// Closing tag, so scan the immediately-following text with the JSX scanning instead
// of regular scanning to avoid treating illegal characters (e.g. '#') as immediate
// scanning errors
node = <JsxOpeningElement>createNode(SyntaxKind.JsxOpeningElement, fullStart);
scanJsxText();
}
else {
parseExpected(SyntaxKind.SlashToken);
parseExpected(SyntaxKind.GreaterThanToken);
if (inExpressionContext) {
parseExpected(SyntaxKind.GreaterThanToken);
}
else {
parseExpected(SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*advance*/ false);
scanJsxText();
}
node = <JsxSelfClosingElement>createNode(SyntaxKind.JsxSelfClosingElement, fullStart);
}
@@ -3406,14 +3422,20 @@ namespace ts {
return elementName;
}
function parseJsxExpression(): JsxExpression {
function parseJsxExpression(inExpressionContext: boolean): JsxExpression {
let node = <JsxExpression>createNode(SyntaxKind.JsxExpression);
parseExpected(SyntaxKind.OpenBraceToken);
if (token !== SyntaxKind.CloseBraceToken) {
node.expression = parseExpression();
}
parseExpected(SyntaxKind.CloseBraceToken);
if (inExpressionContext) {
parseExpected(SyntaxKind.CloseBraceToken);
}
else {
parseExpected(SyntaxKind.CloseBraceToken, /*message*/ undefined, /*advance*/ false);
scanJsxText();
}
return finishNode(node);
}
@@ -3432,7 +3454,7 @@ namespace ts {
node.initializer = parseLiteralNode();
break;
default:
node.initializer = parseJsxExpression();
node.initializer = parseJsxExpression(/*inExpressionContext*/ true);
break;
}
}
@@ -3448,11 +3470,17 @@ namespace ts {
return finishNode(node);
}
function parseJsxClosingElement(): JsxClosingElement {
function parseJsxClosingElement(inExpressionContext: boolean): JsxClosingElement {
let node = <JsxClosingElement>createNode(SyntaxKind.JsxClosingElement);
parseExpected(SyntaxKind.LessThanSlashToken);
node.tagName = parseJsxElementName();
parseExpected(SyntaxKind.GreaterThanToken);
if (inExpressionContext) {
parseExpected(SyntaxKind.GreaterThanToken);
}
else {
parseExpected(SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*advance*/ false);
scanJsxText();
}
return finishNode(node);
}
@@ -5140,7 +5168,7 @@ namespace ts {
// the 'from' keyword can be parsed as a named export when the export clause is unterminated (i.e. `export { from "moduleName";`)
// If we don't have a 'from' keyword, see if we have a string literal such that ASI won't take effect.
if (token === SyntaxKind.FromKeyword || (token === SyntaxKind.StringLiteral && !scanner.hasPrecedingLineBreak())) {
parseExpected(SyntaxKind.FromKeyword)
parseExpected(SyntaxKind.FromKeyword);
node.moduleSpecifier = parseModuleSpecifier();
}
}
@@ -6011,7 +6039,7 @@ namespace ts {
return;
function visitNode(node: IncrementalNode) {
let text = '';
let text = "";
if (aggressiveChecks && shouldCheckNode(node)) {
text = oldText.substring(node.pos, node.end);
}
+274 -74
View File
@@ -8,6 +8,9 @@ namespace ts {
/* @internal */ export let ioWriteTime = 0;
/** The version of the TypeScript compiler release */
let emptyArray: any[] = [];
export const version = "1.6.0";
export function findConfigFile(searchPath: string): string {
@@ -25,6 +28,62 @@ namespace ts {
}
return undefined;
}
export function resolveTripleslashReference(moduleName: string, containingFile: string): string {
let basePath = getDirectoryPath(containingFile);
let referencedFileName = isRootedDiskPath(moduleName) ? moduleName : combinePaths(basePath, moduleName);
return normalizePath(referencedFileName);
}
export function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModule {
// TODO: use different resolution strategy based on compiler options
return legacyNameResolver(moduleName, containingFile, compilerOptions, host);
}
function legacyNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModule {
// module names that contain '!' are used to reference resources and are not resolved to actual files on disk
if (moduleName.indexOf('!') != -1) {
return { resolvedFileName: undefined, failedLookupLocations: [] };
}
let searchPath = getDirectoryPath(containingFile);
let searchName: string;
let failedLookupLocations: string[] = [];
let referencedSourceFile: string;
while (true) {
searchName = normalizePath(combinePaths(searchPath, moduleName));
referencedSourceFile = forEach(supportedExtensions, extension => {
if (extension === ".tsx" && !compilerOptions.jsx) {
// resolve .tsx files only if jsx support is enabled
// 'logical not' handles both undefined and None cases
return undefined;
}
let candidate = searchName + extension;
if (host.fileExists(candidate)) {
return candidate;
}
else {
failedLookupLocations.push(candidate);
}
});
if (referencedSourceFile) {
break;
}
let parentPath = getDirectoryPath(searchPath);
if (parentPath === searchPath) {
break;
}
searchPath = parentPath;
}
return { resolvedFileName: referencedSourceFile, failedLookupLocations };
}
export function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost {
let currentDirectory: string;
@@ -92,7 +151,8 @@ namespace ts {
}
const newLine = getNewLineCharacter(options);
return {
getSourceFile,
getDefaultLibFileName: options => combinePaths(getDirectoryPath(normalizePath(sys.getExecutingFilePath())), getDefaultLibFileName(options)),
@@ -100,7 +160,9 @@ namespace ts {
getCurrentDirectory: () => currentDirectory || (currentDirectory = sys.getCurrentDirectory()),
useCaseSensitiveFileNames: () => sys.useCaseSensitiveFileNames,
getCanonicalFileName,
getNewLine: () => newLine
getNewLine: () => newLine,
fileExists: fileName => sys.fileExists(fileName),
readFile: fileName => sys.readFile(fileName)
};
}
@@ -143,7 +205,7 @@ namespace ts {
}
}
export function createProgram(rootNames: string[], options: CompilerOptions, host?: CompilerHost): Program {
export function createProgram(rootNames: string[], options: CompilerOptions, host?: CompilerHost, oldProgram?: Program): Program {
let program: Program;
let files: SourceFile[] = [];
let diagnostics = createDiagnosticCollection();
@@ -158,24 +220,56 @@ namespace ts {
let start = new Date().getTime();
host = host || createCompilerHost(options);
// initialize resolveModuleNameWorker only if noResolve is false
let resolveModuleNamesWorker: (moduleNames: string[], containingFile: string) => string[];
if (!options.noResolve) {
resolveModuleNamesWorker = host.resolveModuleNames;
if (!resolveModuleNamesWorker) {
resolveModuleNamesWorker = (moduleNames, containingFile) => {
return map(moduleNames, moduleName => {
let moduleResolution = resolveModuleName(moduleName, containingFile, options, host);
return moduleResolution.resolvedFileName;
});
}
}
}
let filesByName = createFileMap<SourceFile>(fileName => host.getCanonicalFileName(fileName));
forEach(rootNames, name => processRootFile(name, /*isDefaultLib:*/ false));
// Do not process the default library if:
// - The '--noLib' flag is used.
// - A 'no-default-lib' reference comment is encountered in
// processing the root files.
if (!skipDefaultLib) {
processRootFile(host.getDefaultLibFileName(options), /*isDefaultLib:*/ true);
if (oldProgram) {
// check properties that can affect structure of the program or module resolution strategy
// if any of these properties has changed - structure cannot be reused
let oldOptions = oldProgram.getCompilerOptions();
if ((oldOptions.module !== options.module) ||
(oldOptions.noResolve !== options.noResolve) ||
(oldOptions.target !== options.target) ||
(oldOptions.noLib !== options.noLib) ||
(oldOptions.jsx !== options.jsx)) {
oldProgram = undefined;
}
}
if (!tryReuseStructureFromOldProgram()) {
forEach(rootNames, name => processRootFile(name, false));
// Do not process the default library if:
// - The '--noLib' flag is used.
// - A 'no-default-lib' reference comment is encountered in
// processing the root files.
if (!skipDefaultLib) {
processRootFile(host.getDefaultLibFileName(options), true);
}
}
verifyCompilerOptions();
// unconditionally set oldProgram to undefined to prevent it from being captured in closure
oldProgram = undefined;
programTime += new Date().getTime() - start;
program = {
getRootFileNames: () => rootNames,
getSourceFile: getSourceFile,
getSourceFiles: () => files,
getCompilerOptions: () => options,
@@ -211,6 +305,82 @@ namespace ts {
return classifiableNames;
}
function tryReuseStructureFromOldProgram(): boolean {
if (!oldProgram) {
return false;
}
Debug.assert(!oldProgram.structureIsReused);
// there is an old program, check if we can reuse its structure
let oldRootNames = oldProgram.getRootFileNames();
if (!arrayIsEqualTo(oldRootNames, rootNames)) {
return false;
}
// check if program source files has changed in the way that can affect structure of the program
let newSourceFiles: SourceFile[] = [];
for (let oldSourceFile of oldProgram.getSourceFiles()) {
let newSourceFile = host.getSourceFile(oldSourceFile.fileName, options.target);
if (!newSourceFile) {
return false;
}
if (oldSourceFile !== newSourceFile) {
if (oldSourceFile.hasNoDefaultLib !== newSourceFile.hasNoDefaultLib) {
// value of no-default-lib has changed
// this will affect if default library is injected into the list of files
return false;
}
// check tripleslash references
if (!arrayIsEqualTo(oldSourceFile.referencedFiles, newSourceFile.referencedFiles, fileReferenceIsEqualTo)) {
// tripleslash references has changed
return false;
}
// check imports
collectExternalModuleReferences(newSourceFile);
if (!arrayIsEqualTo(oldSourceFile.imports, newSourceFile.imports, moduleNameIsEqualTo)) {
// imports has changed
return false;
}
if (resolveModuleNamesWorker) {
let moduleNames = map(newSourceFile.imports, name => name.text);
let resolutions = resolveModuleNamesWorker(moduleNames, newSourceFile.fileName);
// ensure that module resolution results are still correct
for (let i = 0; i < moduleNames.length; ++i) {
let oldResolution = getResolvedModuleFileName(oldSourceFile, moduleNames[i]);
if (oldResolution !== resolutions[i]) {
return false;
}
}
}
// pass the cache of module resolutions from the old source file
newSourceFile.resolvedModules = oldSourceFile.resolvedModules;
}
else {
// file has no changes - use it as is
newSourceFile = oldSourceFile;
}
// if file has passed all checks it should be safe to reuse it
newSourceFiles.push(newSourceFile);
}
// update fileName -> file mapping
for (let file of newSourceFiles) {
filesByName.set(file.fileName, file);
}
files = newSourceFiles;
oldProgram.structureIsReused = true;
return true;
}
function getEmitHost(writeFileCallback?: WriteFileCallback): EmitHost {
return {
getCanonicalFileName: fileName => host.getCanonicalFileName(fileName),
@@ -370,16 +540,66 @@ namespace ts {
function processRootFile(fileName: string, isDefaultLib: boolean) {
processSourceFile(normalizePath(fileName), isDefaultLib);
}
function fileReferenceIsEqualTo(a: FileReference, b: FileReference): boolean {
return a.fileName === b.fileName;
}
function moduleNameIsEqualTo(a: LiteralExpression, b: LiteralExpression): boolean {
return a.text === b.text;
}
function collectExternalModuleReferences(file: SourceFile): void {
if (file.imports) {
return;
}
let imports: LiteralExpression[];
for (let node of file.statements) {
switch (node.kind) {
case SyntaxKind.ImportDeclaration:
case SyntaxKind.ImportEqualsDeclaration:
case SyntaxKind.ExportDeclaration:
let moduleNameExpr = getExternalModuleName(node);
if (!moduleNameExpr || moduleNameExpr.kind !== SyntaxKind.StringLiteral) {
break;
}
if (!(<LiteralExpression>moduleNameExpr).text) {
break;
}
(imports || (imports = [])).push(<LiteralExpression>moduleNameExpr);
break;
case SyntaxKind.ModuleDeclaration:
if ((<ModuleDeclaration>node).name.kind === SyntaxKind.StringLiteral && (node.flags & NodeFlags.Ambient || isDeclarationFile(file))) {
// TypeScript 1.0 spec (April 2014): 12.1.6
// An AmbientExternalModuleDeclaration declares an external module.
// This type of declaration is permitted only in the global module.
// The StringLiteral must specify a top - level external module name.
// Relative external module names are not permitted
forEachChild((<ModuleDeclaration>node).body, node => {
if (isExternalModuleImportEqualsDeclaration(node) &&
getExternalModuleImportEqualsDeclarationExpression(node).kind === SyntaxKind.StringLiteral) {
let moduleName = <LiteralExpression>getExternalModuleImportEqualsDeclarationExpression(node);
// TypeScript 1.0 spec (April 2014): 12.1.6
// An ExternalImportDeclaration in anAmbientExternalModuleDeclaration may reference other external modules
// only through top - level external module names. Relative external module names are not permitted.
if (moduleName) {
(imports || (imports = [])).push(moduleName);
}
}
});
}
break;
}
}
file.imports = imports || emptyArray;
}
function processSourceFile(fileName: string, isDefaultLib: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number) {
let start: number;
let length: number;
let diagnosticArgument: string[];
if (refEnd !== undefined && refPos !== undefined) {
start = refPos;
length = refEnd - refPos;
}
let diagnostic: DiagnosticMessage;
if (hasExtension(fileName)) {
if (!options.allowNonTsExtensions && !forEach(supportedExtensions, extension => fileExtensionIs(host.getCanonicalFileName(fileName), extension))) {
@@ -411,8 +631,8 @@ namespace ts {
}
if (diagnostic) {
if (refFile) {
diagnostics.add(createFileDiagnostic(refFile, start, length, diagnostic, ...diagnosticArgument));
if (refFile !== undefined && refEnd !== undefined && refPos !== undefined) {
diagnostics.add(createFileDiagnostic(refFile, refPos, refEnd - refPos, diagnostic, ...diagnosticArgument));
}
else {
diagnostics.add(createCompilerDiagnostic(diagnostic, ...diagnosticArgument));
@@ -421,7 +641,7 @@ namespace ts {
}
// Get source file from normalized fileName
function findSourceFile(fileName: string, isDefaultLib: boolean, refFile?: SourceFile, refStart?: number, refLength?: number): SourceFile {
function findSourceFile(fileName: string, isDefaultLib: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number): SourceFile {
let canonicalName = host.getCanonicalFileName(normalizeSlashes(fileName));
if (filesByName.contains(canonicalName)) {
// We've already looked for this file, use cached result
@@ -436,8 +656,8 @@ namespace ts {
// We haven't looked for this file, do so now and cache result
let file = host.getSourceFile(fileName, options.target, hostErrorMessage => {
if (refFile) {
diagnostics.add(createFileDiagnostic(refFile, refStart, refLength,
if (refFile !== undefined && refPos !== undefined && refEnd !== undefined) {
diagnostics.add(createFileDiagnostic(refFile, refPos, refEnd - refPos,
Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage));
}
else {
@@ -473,8 +693,13 @@ namespace ts {
if (file && host.useCaseSensitiveFileNames()) {
let sourceFileName = useAbsolutePath ? getNormalizedAbsolutePath(file.fileName, host.getCurrentDirectory()) : file.fileName;
if (canonicalName !== sourceFileName) {
diagnostics.add(createFileDiagnostic(refFile, refStart, refLength,
Diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing, fileName, sourceFileName));
if (refFile !== undefined && refPos !== undefined && refEnd !== undefined) {
diagnostics.add(createFileDiagnostic(refFile, refPos, refEnd - refPos,
Diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing, fileName, sourceFileName));
}
else {
diagnostics.add(createCompilerDiagnostic(Diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing, fileName, sourceFileName));
}
}
}
return file;
@@ -483,60 +708,35 @@ namespace ts {
function processReferencedFiles(file: SourceFile, basePath: string) {
forEach(file.referencedFiles, ref => {
let referencedFileName = isRootedDiskPath(ref.fileName) ? ref.fileName : combinePaths(basePath, ref.fileName);
processSourceFile(normalizePath(referencedFileName), /* isDefaultLib */ false, file, ref.pos, ref.end);
let referencedFileName = resolveTripleslashReference(ref.fileName, file.fileName);
processSourceFile(referencedFileName, /* isDefaultLib */ false, file, ref.pos, ref.end);
});
}
function processImportedModules(file: SourceFile, basePath: string) {
forEach(file.statements, node => {
if (node.kind === SyntaxKind.ImportDeclaration || node.kind === SyntaxKind.ImportEqualsDeclaration || node.kind === SyntaxKind.ExportDeclaration) {
let moduleNameExpr = getExternalModuleName(node);
if (moduleNameExpr && moduleNameExpr.kind === SyntaxKind.StringLiteral) {
let moduleNameText = (<LiteralExpression>moduleNameExpr).text;
if (moduleNameText) {
let searchPath = basePath;
let searchName: string;
while (true) {
searchName = normalizePath(combinePaths(searchPath, moduleNameText));
if (forEach(supportedExtensions, extension => findModuleSourceFile(searchName + extension, moduleNameExpr))) {
break;
}
let parentPath = getDirectoryPath(searchPath);
if (parentPath === searchPath) {
break;
}
searchPath = parentPath;
}
}
function processImportedModules(file: SourceFile, basePath: string) {
collectExternalModuleReferences(file);
if (file.imports.length) {
file.resolvedModules = {};
let oldSourceFile = oldProgram && oldProgram.getSourceFile(file.fileName);
let moduleNames = map(file.imports, name => name.text);
let resolutions = resolveModuleNamesWorker(moduleNames, file.fileName);
for (let i = 0; i < file.imports.length; ++i) {
let resolution = resolutions[i];
setResolvedModuleName(file, moduleNames[i], resolution);
if (resolution) {
findModuleSourceFile(resolution, file.imports[i]);
}
}
else if (node.kind === SyntaxKind.ModuleDeclaration && (<ModuleDeclaration>node).name.kind === SyntaxKind.StringLiteral && (node.flags & NodeFlags.Ambient || isDeclarationFile(file))) {
// TypeScript 1.0 spec (April 2014): 12.1.6
// An AmbientExternalModuleDeclaration declares an external module.
// This type of declaration is permitted only in the global module.
// The StringLiteral must specify a top - level external module name.
// Relative external module names are not permitted
forEachChild((<ModuleDeclaration>node).body, node => {
if (isExternalModuleImportEqualsDeclaration(node) &&
getExternalModuleImportEqualsDeclarationExpression(node).kind === SyntaxKind.StringLiteral) {
let nameLiteral = <LiteralExpression>getExternalModuleImportEqualsDeclarationExpression(node);
let moduleName = nameLiteral.text;
if (moduleName) {
// TypeScript 1.0 spec (April 2014): 12.1.6
// An ExternalImportDeclaration in anAmbientExternalModuleDeclaration may reference other external modules
// only through top - level external module names. Relative external module names are not permitted.
let searchName = normalizePath(combinePaths(basePath, moduleName));
forEach(supportedExtensions, extension => findModuleSourceFile(searchName + extension, nameLiteral));
}
}
});
}
});
}
}
else {
// no imports - drop cached module resolutions
file.resolvedModules = undefined;
}
return;
function findModuleSourceFile(fileName: string, nameLiteral: Expression) {
return findSourceFile(fileName, /* isDefaultLib */ false, file, nameLiteral.pos, nameLiteral.end - nameLiteral.pos);
return findSourceFile(fileName, /* isDefaultLib */ false, file, nameLiteral.pos, nameLiteral.end);
}
}
+65 -12
View File
@@ -319,14 +319,21 @@ namespace ts {
}
/* @internal */
/**
* We assume the first line starts at position 0 and 'position' is non-negative.
*/
export function computeLineAndCharacterOfPosition(lineStarts: number[], position: number) {
let lineNumber = binarySearch(lineStarts, position);
if (lineNumber < 0) {
// If the actual position was not found,
// the binary search returns the negative value of the next line start
// the binary search returns the 2's-complement of the next line start
// e.g. if the line starts at [5, 10, 23, 80] and the position requested was 20
// then the search will return -2
// then the search will return -2.
//
// We want the index of the previous line start, so we subtract 1.
// Review 2's-complement if this is confusing.
lineNumber = ~lineNumber - 1;
Debug.assert(lineNumber !== -1, "position cannot precede the beginning of the file");
}
return {
line: lineNumber,
@@ -401,6 +408,9 @@ namespace ts {
case CharacterCodes.greaterThan:
// Starts of conflict marker trivia
return true;
case CharacterCodes.hash:
// Only if its the beginning can we have #! trivia
return pos === 0;
default:
return ch > CharacterCodes.maxAsciiCharacter;
}
@@ -461,6 +471,13 @@ namespace ts {
}
break;
case CharacterCodes.hash:
if (isShebangTrivia(text, pos)) {
pos = scanShebangTrivia(text, pos);
continue;
}
break;
default:
if (ch > CharacterCodes.maxAsciiCharacter && (isWhiteSpace(ch) || isLineBreak(ch))) {
pos++;
@@ -528,13 +545,31 @@ namespace ts {
return pos;
}
// Extract comments from the given source text starting at the given position. If trailing is
// false, whitespace is skipped until the first line break and comments between that location
// and the next token are returned.If trailing is true, comments occurring between the given
// position and the next line break are returned.The return value is an array containing a
// TextRange for each comment. Single-line comment ranges include the beginning '//' characters
// but not the ending line break. Multi - line comment ranges include the beginning '/* and
// ending '*/' characters.The return value is undefined if no comments were found.
const shebangTriviaRegex = /^#!.*/;
function isShebangTrivia(text: string, pos: number) {
// Shebangs check must only be done at the start of the file
Debug.assert(pos === 0);
return shebangTriviaRegex.test(text);
}
function scanShebangTrivia(text: string, pos: number) {
let shebang = shebangTriviaRegex.exec(text)[0];
pos = pos + shebang.length;
return pos;
}
/**
* Extract comments from text prefixing the token closest following `pos`.
* The return value is an array containing a TextRange for each comment.
* Single-line comment ranges include the beginning '//' characters but not the ending line break.
* Multi - line comment ranges include the beginning '/* and ending '<asterisk>/' characters.
* The return value is undefined if no comments were found.
* @param trailing
* If false, whitespace is skipped until the first line break and comments between that location
* and the next token are returned.
* If true, comments occurring between the given position and the next line break are returned.
*/
function getCommentRanges(text: string, pos: number, trailing: boolean): CommentRange[] {
let result: CommentRange[];
let collecting = trailing || pos === 0;
@@ -617,6 +652,13 @@ namespace ts {
export function getTrailingCommentRanges(text: string, pos: number): CommentRange[] {
return getCommentRanges(text, pos, /*trailing*/ true);
}
/** Optionally, get the shebang */
export function getShebang(text: string): string {
return shebangTriviaRegex.test(text)
? shebangTriviaRegex.exec(text)[0]
: undefined;
}
export function isIdentifierStart(ch: number, languageVersion: ScriptTarget): boolean {
return ch >= CharacterCodes.A && ch <= CharacterCodes.Z || ch >= CharacterCodes.a && ch <= CharacterCodes.z ||
@@ -629,9 +671,8 @@ namespace ts {
ch >= CharacterCodes._0 && ch <= CharacterCodes._9 || ch === CharacterCodes.$ || ch === CharacterCodes._ ||
ch > CharacterCodes.maxAsciiCharacter && isUnicodeIdentifierPart(ch, languageVersion);
}
/* @internal */
// Creates a scanner over a (possibly unspecified) range of a piece of text.
// Creates a scanner over a (possibly unspecified) range of a piece of text.
export function createScanner(languageVersion: ScriptTarget,
skipTrivia: boolean,
languageVariant = LanguageVariant.Standard,
@@ -1087,6 +1128,18 @@ namespace ts {
return token = SyntaxKind.EndOfFileToken;
}
let ch = text.charCodeAt(pos);
// Special handling for shebang
if (ch === CharacterCodes.hash && pos === 0 && isShebangTrivia(text, pos)) {
pos = scanShebangTrivia(text, pos);
if (skipTrivia) {
continue;
}
else {
return token = SyntaxKind.ShebangTrivia;
}
}
switch (ch) {
case CharacterCodes.lineFeed:
case CharacterCodes.carriageReturn:
+16 -14
View File
@@ -30,8 +30,8 @@ namespace ts {
declare var global: any;
declare var __filename: string;
declare var Buffer: {
new (str: string, encoding ?: string): any;
}
new (str: string, encoding?: string): any;
};
declare class Enumerator {
public atEnd(): boolean;
@@ -188,13 +188,13 @@ namespace ts {
};
}
function getNodeSystem(): System {
var _fs = require("fs");
var _path = require("path");
var _os = require('os');
const _fs = require("fs");
const _path = require("path");
const _os = require("os");
var platform: string = _os.platform();
const 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";
const useCaseSensitiveFileNames = platform !== "win32" && platform !== "win64" && platform !== "darwin";
function readFile(fileName: string, encoding?: string): string {
if (!_fs.existsSync(fileName)) {
@@ -228,7 +228,7 @@ namespace ts {
function writeFile(fileName: string, data: string, writeByteOrderMark?: boolean): void {
// If a BOM is required, emit one
if (writeByteOrderMark) {
data = '\uFEFF' + data;
data = "\uFEFF" + data;
}
_fs.writeFileSync(fileName, data, "utf8");
@@ -271,10 +271,10 @@ namespace ts {
newLine: _os.EOL,
useCaseSensitiveFileNames: useCaseSensitiveFileNames,
write(s: string): void {
var buffer = new Buffer(s, 'utf8');
var offset: number = 0;
var toWrite: number = buffer.length;
var written = 0;
const buffer = new Buffer(s, "utf8");
let offset: number = 0;
let toWrite: number = buffer.length;
let written = 0;
// 1 is a standard descriptor for stdout
while ((written = _fs.writeSync(1, buffer, offset, toWrite)) < toWrite) {
offset += written;
@@ -297,7 +297,7 @@ namespace ts {
}
callback(fileName);
};
}
},
resolvePath: function (path: string): string {
return _path.resolve(path);
@@ -334,7 +334,9 @@ namespace ts {
if (typeof WScript !== "undefined" && typeof ActiveXObject === "function") {
return getWScriptSystem();
}
else if (typeof module !== "undefined" && module.exports) {
else if (typeof process !== "undefined" && process.nextTick && !process.browser && typeof require !== "undefined") {
// process and process.nextTick checks if current environment is node-like
// process.browser check excludes webpack and browserify
return getNodeSystem();
}
else {
+12 -11
View File
@@ -3,7 +3,7 @@
namespace ts {
export interface SourceFile {
fileWatcher: FileWatcher;
fileWatcher?: FileWatcher;
}
/**
@@ -14,7 +14,7 @@ namespace ts {
let 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'));
errors.push(createCompilerDiagnostic(Diagnostics.Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1, "en", "ja-jp"));
return false;
}
@@ -49,7 +49,7 @@ namespace ts {
}
// TODO: Add codePage support for readFile?
let fileContents = '';
let fileContents = "";
try {
fileContents = sys.readFile(filePath);
}
@@ -245,7 +245,7 @@ namespace ts {
reportDiagnostic(createCompilerDiagnostic(Diagnostics.Compilation_complete_Watching_for_file_changes));
}
function getSourceFile(fileName: string, languageVersion: ScriptTarget, onError ?: (message: string) => void) {
function getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void) {
// Return existing SourceFile object if one is available
if (cachedProgram) {
let sourceFile = cachedProgram.getSourceFile(fileName);
@@ -355,22 +355,23 @@ namespace ts {
return { program, exitStatus };
function compileProgram(): ExitStatus {
// First get any syntactic errors.
let diagnostics = program.getSyntacticDiagnostics();
reportDiagnostics(diagnostics);
let diagnostics: Diagnostic[];
// First get and report any syntactic errors.
diagnostics = program.getSyntacticDiagnostics();
// If we didn't have any syntactic errors, then also try getting the global and
// semantic errors.
if (diagnostics.length === 0) {
let diagnostics = program.getGlobalDiagnostics();
reportDiagnostics(diagnostics);
diagnostics = program.getOptionsDiagnostics().concat(program.getGlobalDiagnostics());
if (diagnostics.length === 0) {
let diagnostics = program.getSemanticDiagnostics();
reportDiagnostics(diagnostics);
diagnostics = program.getSemanticDiagnostics();
}
}
reportDiagnostics(diagnostics);
// If the user doesn't want us to emit, then we're done at this point.
if (compilerOptions.noEmit) {
return diagnostics.length
+60 -10
View File
@@ -9,6 +9,7 @@ namespace ts {
contains(fileName: string): boolean;
remove(fileName: string): void;
forEachValue(f: (v: T) => void): void;
clear(): void;
}
export interface TextRange {
@@ -17,6 +18,7 @@ namespace ts {
}
// token > SyntaxKind.Identifer => token is a keyword
// Also, If you add a new SyntaxKind be sure to keep the `Markers` section at the bottom in sync
export const enum SyntaxKind {
Unknown,
EndOfFileToken,
@@ -24,6 +26,8 @@ namespace ts {
MultiLineCommentTrivia,
NewLineTrivia,
WhitespaceTrivia,
// We detect and preserve #! on the first line
ShebangTrivia,
// We detect and provide better error recovery when we encounter a git merge marker. This
// allows us to edit files with git-conflict markers in them in a much more pleasant manner.
ConflictMarkerTrivia,
@@ -583,9 +587,9 @@ namespace ts {
* Several node kinds share function-like features such as a signature,
* a name, and a body. These nodes should extend FunctionLikeDeclaration.
* Examples:
* FunctionDeclaration
* MethodDeclaration
* AccessorDeclaration
* - FunctionDeclaration
* - MethodDeclaration
* - AccessorDeclaration
*/
export interface FunctionLikeDeclaration extends SignatureDeclaration {
_functionLikeDeclarationBrand: any;
@@ -1240,6 +1244,10 @@ namespace ts {
moduleName: string;
referencedFiles: FileReference[];
languageVariant: LanguageVariant;
// this map is used by transpiler to supply alternative names for dependencies (i.e. in case of bundling)
/* @internal */
renamedDependencies?: Map<string>;
/**
* lib.d.ts should have a reference comment like
@@ -1272,8 +1280,12 @@ namespace ts {
// Stores a line map for the file.
// This field should never be used directly to obtain line map, use getLineMap function instead.
/* @internal */ lineMap: number[];
/* @internal */ classifiableNames?: Map<string>;
// Stores a mapping 'external module reference text' -> 'resolved file name' | undefined
// It is used to resolve module names in the checker.
// Content of this fiels should never be used directly - use getResolvedModuleFileName/setResolvedModuleFileName functions instead
/* @internal */ resolvedModules: Map<string>;
/* @internal */ imports: LiteralExpression[];
}
export interface ScriptReferenceHost {
@@ -1282,7 +1294,7 @@ namespace ts {
getCurrentDirectory(): string;
}
export interface ParseConfigHost {
export interface ParseConfigHost extends ModuleResolutionHost {
readDirectory(rootDir: string, extension: string, exclude: string[]): string[];
}
@@ -1300,6 +1312,12 @@ namespace ts {
}
export interface Program extends ScriptReferenceHost {
/**
* Get a list of root file names that were passed to a 'createProgram'
*/
getRootFileNames(): string[]
/**
* Get a list of files in the program
*/
@@ -1340,6 +1358,9 @@ namespace ts {
/* @internal */ getIdentifierCount(): number;
/* @internal */ getSymbolCount(): number;
/* @internal */ getTypeCount(): number;
// For testing purposes only.
/* @internal */ structureIsReused?: boolean;
}
export interface SourceMapSpan {
@@ -1431,6 +1452,7 @@ namespace ts {
getJsxElementAttributesType(elementNode: JsxOpeningLikeElement): Type;
getJsxIntrinsicTagNames(): Symbol[];
isOptionalParameter(node: ParameterDeclaration): boolean;
// Should not be called directly. Should only be accessed through the Program instance.
/* @internal */ getDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[];
@@ -1574,7 +1596,8 @@ namespace ts {
getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number;
getBlockScopedVariableId(node: Identifier): number;
getReferencedValueDeclaration(reference: Identifier): Declaration;
getTypeReferenceSerializationKind(node: TypeReferenceNode): TypeReferenceSerializationKind;
getTypeReferenceSerializationKind(typeName: EntityName): TypeReferenceSerializationKind;
isOptionalParameter(node: ParameterDeclaration): boolean;
}
export const enum SymbolFlags {
@@ -1768,7 +1791,9 @@ namespace ts {
ContainsUndefinedOrNull = 0x00200000, // Type is or contains Undefined or Null type
/* @internal */
ContainsObjectLiteral = 0x00400000, // Type is or contains object literal type
ESSymbol = 0x00800000, // Type of symbol primitive introduced in ES6
/* @internal */
ContainsAnyFunctionType = 0x00800000, // Type is or contains object literal type
ESSymbol = 0x01000000, // Type of symbol primitive introduced in ES6
/* @internal */
Intrinsic = Any | String | Number | Boolean | ESSymbol | Void | Undefined | Null,
@@ -1777,10 +1802,12 @@ namespace ts {
StringLike = String | StringLiteral,
NumberLike = Number | Enum,
ObjectType = Class | Interface | Reference | Tuple | Anonymous,
UnionOrIntersection = Union | Intersection,
UnionOrIntersection = Union | Intersection,
StructuredType = ObjectType | Union | Intersection,
/* @internal */
RequiresWidening = ContainsUndefinedOrNull | ContainsObjectLiteral
RequiresWidening = ContainsUndefinedOrNull | ContainsObjectLiteral,
/* @internal */
PropagatingFlags = ContainsUndefinedOrNull | ContainsObjectLiteral | ContainsAnyFunctionType
}
// Properties common to all types
@@ -2220,9 +2247,23 @@ namespace ts {
byteOrderMark = 0xFEFF,
tab = 0x09, // \t
verticalTab = 0x0B, // \v
}
export interface ModuleResolutionHost {
fileExists(fileName: string): boolean;
// readFile function is used to read arbitrary text files on disk, i.e. when resolution procedure needs the content of 'package.json'
// to determine location of bundled typings for node module
readFile(fileName: string): string;
}
export interface ResolvedModule {
resolvedFileName: string;
failedLookupLocations: string[];
}
export type ModuleNameResolver = (moduleName: string, containingFile: string, options: CompilerOptions, host: ModuleResolutionHost) => ResolvedModule;
export interface CompilerHost {
export interface CompilerHost extends ModuleResolutionHost {
getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void): SourceFile;
getCancellationToken?(): CancellationToken;
getDefaultLibFileName(options: CompilerOptions): string;
@@ -2231,6 +2272,15 @@ namespace ts {
getCanonicalFileName(fileName: string): string;
useCaseSensitiveFileNames(): boolean;
getNewLine(): string;
/*
* CompilerHost must either implement resolveModuleNames (in case if it wants to be completely in charge of
* module name resolution) or provide implementation for methods from ModuleResolutionHost (in this case compiler
* will appply built-in module resolution logic and use members of ModuleResolutionHost to ask host specific questions).
* If resolveModuleNames is implemented then implementation for members from ModuleResolutionHost can be just
* 'throw new Error("NotImplemented")'
*/
resolveModuleNames?(moduleNames: string[], containingFile: string): string[];
}
export interface TextSpan {
+74 -20
View File
@@ -80,6 +80,41 @@ namespace ts {
return node.end - node.pos;
}
export function arrayIsEqualTo<T>(arr1: T[], arr2: T[], comparer?: (a: T, b: T) => boolean): boolean {
if (!arr1 || !arr2) {
return arr1 === arr2;
}
if (arr1.length !== arr2.length) {
return false;
}
for (let i = 0; i < arr1.length; ++i) {
let equals = comparer ? comparer(arr1[i], arr2[i]) : arr1[i] === arr2[i];
if (!equals) {
return false;
}
}
return true;
}
export function hasResolvedModuleName(sourceFile: SourceFile, moduleNameText: string): boolean {
return sourceFile.resolvedModules && hasProperty(sourceFile.resolvedModules, moduleNameText);
}
export function getResolvedModuleFileName(sourceFile: SourceFile, moduleNameText: string): string {
return hasResolvedModuleName(sourceFile, moduleNameText) ? sourceFile.resolvedModules[moduleNameText] : undefined;
}
export function setResolvedModuleName(sourceFile: SourceFile, moduleNameText: string, resolvedFileName: string): void {
if (!sourceFile.resolvedModules) {
sourceFile.resolvedModules = {};
}
sourceFile.resolvedModules[moduleNameText] = resolvedFileName;
}
// Returns true if this node contains a parse error anywhere underneath it.
export function containsParseError(node: Node): boolean {
aggregateChildData(node);
@@ -205,7 +240,7 @@ namespace ts {
// Make an identifier from an external module name by extracting the string after the last "/" and replacing
// all non-alphanumeric characters with underscores
export function makeIdentifierFromModuleName(moduleName: string): string {
return getBaseFileName(moduleName).replace(/\W/g, "_");
return getBaseFileName(moduleName).replace(/^(\d)/, "_$1").replace(/\W/g, "_");
}
export function isBlockOrCatchScoped(declaration: Declaration) {
@@ -381,24 +416,15 @@ namespace ts {
}
export function getLeadingCommentRangesOfNode(node: Node, sourceFileOfNode: SourceFile) {
// If parameter/type parameter, the prev token trailing comments are part of this node too
if (node.kind === SyntaxKind.Parameter || node.kind === SyntaxKind.TypeParameter) {
// e.g. (/** blah */ a, /** blah */ b);
// e.g.: (
// /** blah */ a,
// /** blah */ b);
return concatenate(
getTrailingCommentRanges(sourceFileOfNode.text, node.pos),
getLeadingCommentRanges(sourceFileOfNode.text, node.pos));
}
else {
return getLeadingCommentRanges(sourceFileOfNode.text, node.pos);
}
return getLeadingCommentRanges(sourceFileOfNode.text, node.pos);
}
export function getJsDocComments(node: Node, sourceFileOfNode: SourceFile) {
return filter(getLeadingCommentRangesOfNode(node, sourceFileOfNode), isJsDocComment);
let commentRanges = (node.kind === SyntaxKind.Parameter || node.kind === SyntaxKind.TypeParameter) ?
concatenate(getTrailingCommentRanges(sourceFileOfNode.text, node.pos),
getLeadingCommentRanges(sourceFileOfNode.text, node.pos)) :
getLeadingCommentRangesOfNode(node, sourceFileOfNode);
return filter(commentRanges, isJsDocComment);
function isJsDocComment(comment: CommentRange) {
// True if the comment starts with '/**' but not if it is '/**/'
@@ -615,6 +641,20 @@ namespace ts {
return false;
}
export function introducesArgumentsExoticObject(node: Node) {
switch (node.kind) {
case SyntaxKind.MethodDeclaration:
case SyntaxKind.MethodSignature:
case SyntaxKind.Constructor:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.FunctionExpression:
return true;
}
return false;
}
export function isFunctionBlock(node: Node) {
return node && node.kind === SyntaxKind.Block && isFunctionLike(node.parent);
}
@@ -988,15 +1028,13 @@ namespace ts {
if (node) {
switch (node.kind) {
case SyntaxKind.Parameter:
return (<ParameterDeclaration>node).questionToken !== undefined;
case SyntaxKind.MethodDeclaration:
case SyntaxKind.MethodSignature:
return (<MethodDeclaration>node).questionToken !== undefined;
case SyntaxKind.ShorthandPropertyAssignment:
case SyntaxKind.PropertyAssignment:
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.PropertySignature:
return (<PropertyDeclaration>node).questionToken !== undefined;
return (<ParameterDeclaration | MethodDeclaration | PropertyDeclaration>node).questionToken !== undefined;
}
}
@@ -1424,6 +1462,22 @@ namespace ts {
return isFunctionLike(n) || n.kind === SyntaxKind.ModuleDeclaration || n.kind === SyntaxKind.SourceFile;
}
export function cloneEntityName(node: EntityName): EntityName {
if (node.kind === SyntaxKind.Identifier) {
let clone = <Identifier>createSynthesizedNode(SyntaxKind.Identifier);
clone.text = (<Identifier>node).text;
return clone;
}
else {
let clone = <QualifiedName>createSynthesizedNode(SyntaxKind.QualifiedName);
clone.left = cloneEntityName((<QualifiedName>node).left);
clone.left.parent = clone;
clone.right = <Identifier>cloneEntityName((<QualifiedName>node).right);
clone.right.parent = clone;
return clone;
}
}
export function nodeIsSynthesized(node: Node): boolean {
return node.pos === -1;
}
@@ -1868,7 +1922,7 @@ namespace ts {
function writeTrimmedCurrentLine(pos: number, nextLineStart: number) {
let end = Math.min(comment.end, nextLineStart - 1);
let currentLineText = currentSourceFile.text.substring(pos, end).replace(/^\s+|\s+$/g, '');
let currentLineText = currentSourceFile.text.substring(pos, end).replace(/^\s+|\s+$/g, "");
if (currentLineText) {
// trimmed forward and ending spaces text
writer.write(currentLineText);
+60 -60
View File
@@ -1,6 +1,6 @@
/// <reference path='harness.ts' />
/// <reference path='runnerbase.ts' />
/// <reference path='typeWriter.ts' />
/// <reference path="harness.ts" />
/// <reference path="runnerbase.ts" />
/// <reference path="typeWriter.ts" />
const enum CompilerTestType {
Conformance,
@@ -9,7 +9,7 @@ const enum CompilerTestType {
}
class CompilerBaselineRunner extends RunnerBase {
private basePath = 'tests/cases';
private basePath = "tests/cases";
private testSuiteName: string;
private errors: boolean;
private emit: boolean;
@@ -25,21 +25,21 @@ class CompilerBaselineRunner extends RunnerBase {
this.decl = true;
this.output = true;
if (testType === CompilerTestType.Conformance) {
this.testSuiteName = 'conformance';
this.testSuiteName = "conformance";
}
else if (testType === CompilerTestType.Regressions) {
this.testSuiteName = 'compiler';
this.testSuiteName = "compiler";
}
else if (testType === CompilerTestType.Test262) {
this.testSuiteName = 'test262';
this.testSuiteName = "test262";
} else {
this.testSuiteName = 'compiler'; // default to this for historical reasons
this.testSuiteName = "compiler"; // default to this for historical reasons
}
this.basePath += '/' + this.testSuiteName;
this.basePath += "/" + this.testSuiteName;
}
public checkTestCodeOutput(fileName: string) {
describe('compiler tests for ' + fileName, () => {
describe("compiler tests for " + fileName, () => {
// Mocha holds onto the closure environment of the describe callback even after the test is done.
// Everything declared here should be cleared out in the "after" callback.
let justName: string;
@@ -64,14 +64,14 @@ class CompilerBaselineRunner extends RunnerBase {
let createNewInstance = false;
before(() => {
justName = fileName.replace(/^.*[\\\/]/, ''); // strips the fileName from the path.
justName = fileName.replace(/^.*[\\\/]/, ""); // strips the fileName from the path.
content = Harness.IO.readFile(fileName);
testCaseContent = Harness.TestCaseParser.makeUnitsFromTest(content, fileName);
units = testCaseContent.testUnitData;
tcSettings = testCaseContent.settings;
createNewInstance = false;
lastUnit = units[units.length - 1];
rootDir = lastUnit.originalFilePath.indexOf('conformance') === -1 ? 'tests/cases/compiler/' : lastUnit.originalFilePath.substring(0, lastUnit.originalFilePath.lastIndexOf('/')) + '/';
rootDir = lastUnit.originalFilePath.indexOf("conformance") === -1 ? "tests/cases/compiler/" : lastUnit.originalFilePath.substring(0, lastUnit.originalFilePath.lastIndexOf("/")) + "/";
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,
@@ -106,7 +106,7 @@ class CompilerBaselineRunner extends RunnerBase {
eventually to remove this limitation. */
for (let i = 0; i < tcSettings.length; ++i) {
// noImplicitAny is passed to getCompiler, but target is just passed in the settings blob to setCompilerSettings
if (!createNewInstance && (tcSettings[i].flag == "noimplicitany" || tcSettings[i].flag === 'target')) {
if (!createNewInstance && (tcSettings[i].flag == "noimplicitany" || tcSettings[i].flag === "target")) {
harnessCompiler = Harness.Compiler.getCompiler();
harnessCompiler.setCompilerSettings(tcSettings);
createNewInstance = true;
@@ -148,9 +148,9 @@ class CompilerBaselineRunner extends RunnerBase {
}
// check errors
it('Correct errors for ' + fileName, () => {
it("Correct errors for " + fileName, () => {
if (this.errors) {
Harness.Baseline.runBaseline('Correct errors for ' + fileName, justName.replace(/\.tsx?$/, '.errors.txt'), (): string => {
Harness.Baseline.runBaseline("Correct errors for " + fileName, justName.replace(/\.tsx?$/, ".errors.txt"), (): string => {
if (result.errors.length === 0) return null;
return getErrorBaseline(toBeCompiled, otherFiles, result);
});
@@ -158,12 +158,12 @@ class CompilerBaselineRunner extends RunnerBase {
});
// Source maps?
it('Correct sourcemap content for ' + fileName, () => {
it("Correct sourcemap content for " + fileName, () => {
if (options.sourceMap || options.inlineSourceMap) {
Harness.Baseline.runBaseline('Correct sourcemap content for ' + fileName, justName.replace(/\.tsx?$/, '.sourcemap.txt'), () => {
Harness.Baseline.runBaseline("Correct sourcemap content for " + fileName, justName.replace(/\.tsx?$/, ".sourcemap.txt"), () => {
let record = result.getSourceMapRecord();
if (options.noEmitOnError && result.errors.length !== 0 && record === undefined) {
// Because of the noEmitOnError option no files are created. We need to return null because baselining isn't required.
// Because of the noEmitOnError option no files are created. We need to return null because baselining isn"t required.
return null;
}
return record;
@@ -171,35 +171,35 @@ class CompilerBaselineRunner extends RunnerBase {
}
});
it('Correct JS output for ' + fileName, () => {
if (!ts.fileExtensionIs(lastUnit.name, '.d.ts') && this.emit) {
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.');
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(/\.tsx?/, '.js'), () => {
let tsCode = '';
Harness.Baseline.runBaseline("Correct JS output for " + fileName, justName.replace(/\.tsx?/, ".js"), () => {
let tsCode = "";
let tsSources = otherFiles.concat(toBeCompiled);
if (tsSources.length > 1) {
tsCode += '//// [' + fileName + '] ////\r\n\r\n';
tsCode += "//// [" + fileName + "] ////\r\n\r\n";
}
for (let 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' : '');
tsCode += "//// [" + Harness.Path.getFileName(tsSources[i].unitName) + "]\r\n";
tsCode += tsSources[i].content + (i < (tsSources.length - 1) ? "\r\n" : "");
}
let jsCode = '';
let jsCode = "";
for (let i = 0; i < result.files.length; i++) {
jsCode += '//// [' + Harness.Path.getFileName(result.files[i].fileName) + ']\r\n';
jsCode += "//// [" + Harness.Path.getFileName(result.files[i].fileName) + "]\r\n";
jsCode += getByteOrderMarkText(result.files[i]);
jsCode += result.files[i].code;
}
if (result.declFilesCode.length > 0) {
jsCode += '\r\n\r\n';
jsCode += "\r\n\r\n";
for (let i = 0; i < result.declFilesCode.length; i++) {
jsCode += '//// [' + Harness.Path.getFileName(result.declFilesCode[i].fileName) + ']\r\n';
jsCode += "//// [" + Harness.Path.getFileName(result.declFilesCode[i].fileName) + "]\r\n";
jsCode += getByteOrderMarkText(result.declFilesCode[i]);
jsCode += result.declFilesCode[i].code;
}
@@ -210,13 +210,13 @@ class CompilerBaselineRunner extends RunnerBase {
}, options);
if (declFileCompilationResult && declFileCompilationResult.declResult.errors.length) {
jsCode += '\r\n\r\n//// [DtsFileErrors]\r\n';
jsCode += '\r\n\r\n';
jsCode += "\r\n\r\n//// [DtsFileErrors]\r\n";
jsCode += "\r\n\r\n";
jsCode += getErrorBaseline(declFileCompilationResult.declInputFiles, declFileCompilationResult.declOtherFiles, declFileCompilationResult.declResult);
}
if (jsCode.length > 0) {
return tsCode + '\r\n\r\n' + jsCode;
return tsCode + "\r\n\r\n" + jsCode;
} else {
return null;
}
@@ -224,28 +224,28 @@ class CompilerBaselineRunner extends RunnerBase {
}
});
it('Correct Sourcemap output for ' + fileName, () => {
it("Correct Sourcemap output for " + fileName, () => {
if (options.inlineSourceMap) {
if (result.sourceMaps.length > 0) {
throw new Error('No sourcemap files should be generated if inlineSourceMaps was set.');
throw new Error("No sourcemap files should be generated if inlineSourceMaps was set.");
}
return null;
}
else if (options.sourceMap) {
if (result.sourceMaps.length !== result.files.length) {
throw new Error('Number of sourcemap files should be same as js files.');
throw new Error("Number of sourcemap files should be same as js files.");
}
Harness.Baseline.runBaseline('Correct Sourcemap output for ' + fileName, justName.replace(/\.tsx?/, '.js.map'), () => {
Harness.Baseline.runBaseline("Correct Sourcemap output for " + fileName, justName.replace(/\.tsx?/, ".js.map"), () => {
if (options.noEmitOnError && result.errors.length !== 0 && result.sourceMaps.length === 0) {
// We need to return null here or the runBaseLine will actually create a empty file.
// Baselining isn't required here because there is no output.
return null;
}
let sourceMapCode = '';
let sourceMapCode = "";
for (let i = 0; i < result.sourceMaps.length; i++) {
sourceMapCode += '//// [' + Harness.Path.getFileName(result.sourceMaps[i].fileName) + ']\r\n';
sourceMapCode += "//// [" + Harness.Path.getFileName(result.sourceMaps[i].fileName) + "]\r\n";
sourceMapCode += getByteOrderMarkText(result.sourceMaps[i]);
sourceMapCode += result.sourceMaps[i].code;
}
@@ -255,7 +255,7 @@ class CompilerBaselineRunner extends RunnerBase {
}
});
it('Correct type/symbol baselines for ' + fileName, () => {
it("Correct type/symbol baselines for " + fileName, () => {
if (fileName.indexOf("APISample") >= 0) {
return;
}
@@ -317,15 +317,15 @@ class CompilerBaselineRunner extends RunnerBase {
let fullBaseLine = generateBaseLine(fullResults, isSymbolBaseLine);
let pullBaseLine = generateBaseLine(pullResults, isSymbolBaseLine);
let fullExtension = isSymbolBaseLine ? '.symbols' : '.types';
let pullExtension = isSymbolBaseLine ? '.symbols.pull' : '.types.pull';
let fullExtension = isSymbolBaseLine ? ".symbols" : ".types";
let pullExtension = isSymbolBaseLine ? ".symbols.pull" : ".types.pull";
if (fullBaseLine !== pullBaseLine) {
Harness.Baseline.runBaseline('Correct full information for ' + fileName, justName.replace(/\.tsx?/, fullExtension), () => fullBaseLine);
Harness.Baseline.runBaseline('Correct pull information for ' + fileName, justName.replace(/\.tsx?/, pullExtension), () => pullBaseLine);
Harness.Baseline.runBaseline("Correct full information for " + fileName, justName.replace(/\.tsx?/, fullExtension), () => fullBaseLine);
Harness.Baseline.runBaseline("Correct pull information for " + fileName, justName.replace(/\.tsx?/, pullExtension), () => pullBaseLine);
}
else {
Harness.Baseline.runBaseline('Correct information for ' + fileName, justName.replace(/\.tsx?/, fullExtension), () => fullBaseLine);
Harness.Baseline.runBaseline("Correct information for " + fileName, justName.replace(/\.tsx?/, fullExtension), () => fullBaseLine);
}
}
@@ -334,7 +334,7 @@ class CompilerBaselineRunner extends RunnerBase {
let typeMap: { [fileName: string]: { [lineNum: number]: string[]; } } = {};
allFiles.forEach(file => {
let codeLines = file.content.split('\n');
let codeLines = file.content.split("\n");
typeWriterResults[file.unitName].forEach(result => {
if (isSymbolBaseline && !result.symbol) {
return;
@@ -354,30 +354,30 @@ class CompilerBaselineRunner extends RunnerBase {
typeMap[file.unitName][result.line] = typeInfo;
});
typeLines.push('=== ' + file.unitName + ' ===\r\n');
typeLines.push("=== " + file.unitName + " ===\r\n");
for (let i = 0; i < codeLines.length; i++) {
let currentCodeLine = codeLines[i];
typeLines.push(currentCodeLine + '\r\n');
typeLines.push(currentCodeLine + "\r\n");
if (typeMap[file.unitName]) {
let typeInfo = typeMap[file.unitName][i];
if (typeInfo) {
typeInfo.forEach(ty => {
typeLines.push('>' + ty + '\r\n');
typeLines.push(">" + ty + "\r\n");
});
if (i + 1 < codeLines.length && (codeLines[i + 1].match(/^\s*[{|}]\s*$/) || codeLines[i + 1].trim() === '')) {
if (i + 1 < codeLines.length && (codeLines[i + 1].match(/^\s*[{|}]\s*$/) || codeLines[i + 1].trim() === "")) {
}
else {
typeLines.push('\r\n');
typeLines.push("\r\n");
}
}
}
else {
typeLines.push('No type information for this code.');
typeLines.push("No type information for this code.");
}
}
});
return typeLines.join('');
return typeLines.join("");
}
}
});
@@ -385,7 +385,7 @@ class CompilerBaselineRunner extends RunnerBase {
}
public initializeTests() {
describe(this.testSuiteName + ' tests', () => {
describe(this.testSuiteName + " tests", () => {
describe("Setup compiler for compiler baselines", () => {
let harnessCompiler = Harness.Compiler.getCompiler();
this.parseOptions();
@@ -416,23 +416,23 @@ class CompilerBaselineRunner extends RunnerBase {
this.decl = false;
this.output = false;
let opts = this.options.split(',');
let opts = this.options.split(",");
for (let i = 0; i < opts.length; i++) {
switch (opts[i]) {
case 'error':
case "error":
this.errors = true;
break;
case 'emit':
case "emit":
this.emit = true;
break;
case 'decl':
case "decl":
this.decl = true;
break;
case 'output':
case "output":
this.output = true;
break;
default:
throw new Error('unsupported flag');
throw new Error("unsupported flag");
}
}
}
+330 -228
View File
File diff suppressed because it is too large Load Diff
+42 -37
View File
@@ -1,10 +1,11 @@
///<reference path='fourslash.ts' />
///<reference path='harness.ts'/>
///<reference path='runnerbase.ts' />
///<reference path="fourslash.ts" />
///<reference path="harness.ts"/>
///<reference path="runnerbase.ts" />
const enum FourSlashTestType {
Native,
Shims,
ShimsWithPreprocess,
Server
}
@@ -16,16 +17,20 @@ class FourSlashRunner extends RunnerBase {
super();
switch (testType) {
case FourSlashTestType.Native:
this.basePath = 'tests/cases/fourslash';
this.testSuiteName = 'fourslash';
this.basePath = "tests/cases/fourslash";
this.testSuiteName = "fourslash";
break;
case FourSlashTestType.Shims:
this.basePath = 'tests/cases/fourslash/shims';
this.testSuiteName = 'fourslash-shims';
this.basePath = "tests/cases/fourslash/shims";
this.testSuiteName = "fourslash-shims";
break;
case FourSlashTestType.ShimsWithPreprocess:
this.basePath = 'tests/cases/fourslash/shims-pp';
this.testSuiteName = 'fourslash-shims-pp';
break;
case FourSlashTestType.Server:
this.basePath = 'tests/cases/fourslash/server';
this.testSuiteName = 'fourslash-server';
this.basePath = "tests/cases/fourslash/server";
this.testSuiteName = "fourslash-server";
break;
}
}
@@ -35,25 +40,25 @@ class FourSlashRunner extends RunnerBase {
this.tests = this.enumerateFiles(this.basePath, /\.ts/i, { recursive: false });
}
describe(this.testSuiteName + ' tests', () => {
describe(this.testSuiteName + " tests", () => {
this.tests.forEach((fn: string) => {
describe(fn, () => {
fn = ts.normalizeSlashes(fn);
let justName = fn.replace(/^.*[\\\/]/, '');
let justName = fn.replace(/^.*[\\\/]/, "");
// Convert to relative path
let testIndex = fn.indexOf('tests/');
let testIndex = fn.indexOf("tests/");
if (testIndex >= 0) fn = fn.substr(testIndex);
if (justName && !justName.match(/fourslash\.ts$/i) && !justName.match(/\.d\.ts$/i)) {
it(this.testSuiteName + ' test ' + justName + ' runs correctly', () => {
it(this.testSuiteName + " test " + justName + " runs correctly", () => {
FourSlash.runFourSlashTest(this.basePath, this.testType, fn);
});
}
});
});
describe('Generate Tao XML', () => {
describe("Generate Tao XML", () => {
let invalidReasons: any = {};
FourSlash.xmlData.forEach(xml => {
if (xml.invalidReason !== null) {
@@ -69,37 +74,37 @@ class FourSlashRunner extends RunnerBase {
invalidReport.sort((lhs, rhs) => lhs.count > rhs.count ? -1 : lhs.count === rhs.count ? 0 : 1);
let lines: string[] = [];
lines.push('<!-- Blocked Test Report');
lines.push("<!-- Blocked Test Report");
invalidReport.forEach((reasonAndCount) => {
lines.push(reasonAndCount.count + ' tests blocked by ' + reasonAndCount.reason);
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>');
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 + ' -->');
lines.push("<!-- Skipped " + xml.originalName + ", reason: " + xml.invalidReason + " -->");
} else {
lines.push(' <Scenario Name="' + xml.originalName + '">');
lines.push(" <Scenario Name=\"" + xml.originalName + "\">");
xml.actions.forEach(action => {
lines.push(' ' + action);
lines.push(" " + action);
});
lines.push(' </Scenario>');
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'));
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"));
});
});
}
@@ -108,6 +113,6 @@ class FourSlashRunner extends RunnerBase {
class GeneratedFourslashRunner extends FourSlashRunner {
constructor(testType: FourSlashTestType) {
super(testType);
this.basePath += '/generated/';
this.basePath += "/generated/";
}
}
+184 -177
View File
@@ -14,24 +14,27 @@
// limitations under the License.
//
/// <reference path='..\services\services.ts' />
/// <reference path='..\services\shims.ts' />
/// <reference path='..\server\session.ts' />
/// <reference path='..\server\client.ts' />
/// <reference path='..\server\node.d.ts' />
/// <reference path='external\mocha.d.ts'/>
/// <reference path='external\chai.d.ts'/>
/// <reference path='sourceMapRecorder.ts'/>
/// <reference path='runnerbase.ts'/>
/// <reference path="..\services\services.ts" />
/// <reference path="..\services\shims.ts" />
/// <reference path="..\server\session.ts" />
/// <reference path="..\server\client.ts" />
/// <reference path="..\server\node.d.ts" />
/// <reference path="external\mocha.d.ts"/>
/// <reference path="external\chai.d.ts"/>
/// <reference path="sourceMapRecorder.ts"/>
/// <reference path="runnerbase.ts"/>
var Buffer: BufferConstructor = require('buffer').Buffer;
// Block scoped definitions work poorly for global variables, temporarily enable var
/* tslint:disable:no-var-keyword */
var Buffer: BufferConstructor = require("buffer").Buffer;
// this will work in the browser via browserify
var _chai: typeof chai = require('chai');
var _chai: typeof chai = require("chai");
var assert: typeof _chai.assert = _chai.assert;
var expect: typeof _chai.expect = _chai.expect;
declare var __dirname: string; // Node-specific
var global = <any>Function("return this").call(null);
/* tslint:enable:no-var-keyword */
module Utils {
// Setup some globals based on the current environment
@@ -63,7 +66,7 @@ module Utils {
eval(fileContents);
break;
case ExecutionEnvironment.Node:
let vm = require('vm');
let vm = require("vm");
if (nodeContext) {
vm.runInNewContext(fileContents, nodeContext, fileName);
} else {
@@ -71,7 +74,7 @@ module Utils {
}
break;
default:
throw new Error('Unknown context');
throw new Error("Unknown context");
}
}
@@ -80,9 +83,9 @@ module Utils {
// Split up the input file by line
// Note: IE JS engine incorrectly handles consecutive delimiters here when using RegExp split, so
// we have to use string-based splitting instead and try to figure out the delimiting chars
let lines = content.split('\r\n');
let lines = content.split("\r\n");
if (lines.length === 1) {
lines = content.split('\n');
lines = content.split("\n");
if (lines.length === 1) {
lines = content.split("\r");
@@ -93,7 +96,7 @@ module Utils {
/** Reads a file under /tests */
export function readTestFile(path: string) {
if (path.indexOf('tests') < 0) {
if (path.indexOf("tests") < 0) {
path = "tests/" + path;
}
@@ -388,7 +391,7 @@ module Utils {
module Harness.Path {
export function getFileName(fullPath: string) {
return fullPath.replace(/^.*[\\\/]/, '');
return fullPath.replace(/^.*[\\\/]/, "");
}
export function filePath(fullPath: string) {
@@ -412,6 +415,7 @@ module Harness {
log(text: string): void;
getMemoryUsage?(): number;
}
export var IO: IO;
module IOImpl {
declare class Enumerator {
@@ -484,8 +488,8 @@ module Harness {
declare let require: any;
let fs: any, pathModule: any;
if (require) {
fs = require('fs');
pathModule = require('path');
fs = require("fs");
pathModule = require("path");
} else {
fs = pathModule = {};
}
@@ -493,7 +497,7 @@ module Harness {
export let readFile: typeof IO.readFile = ts.sys.readFile;
export let writeFile: typeof IO.writeFile = ts.sys.writeFile;
export let fileExists: typeof IO.fileExists = fs.existsSync;
export let log: typeof IO.log = console.log;
export let log: typeof IO.log = s => console.log(s);
export function createDirectory(path: string) {
if (!directoryExists(path)) {
@@ -559,8 +563,8 @@ module Harness {
let serverRoot = "http://localhost:8888/";
// Unused?
let newLine = '\r\n';
let currentDirectory = () => '';
let newLine = "\r\n";
let currentDirectory = () => "";
let supportsCodePage = () => false;
module Http {
@@ -606,9 +610,9 @@ module Harness {
export function writeToServerSync(url: string, action: string, contents?: string): XHRResponse {
let xhr = new XMLHttpRequest();
try {
let actionMsg = '?action=' + action;
xhr.open('POST', url + actionMsg, false);
xhr.setRequestHeader('Access-Control-Allow-Origin', '*');
let actionMsg = "?action=" + action;
xhr.open("POST", url + actionMsg, false);
xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
xhr.send(contents);
}
catch (e) {
@@ -624,7 +628,7 @@ module Harness {
}
export function deleteFile(path: string) {
Http.writeToServerSync(serverRoot + path, 'DELETE', null);
Http.writeToServerSync(serverRoot + path, "DELETE", null);
}
export function directoryExists(path: string): boolean {
@@ -637,15 +641,15 @@ module Harness {
if (dirPath.match(/localhost:\d+$/) || dirPath.match(/localhost:\d+\/$/)) {
dirPath = null;
// path + fileName
} else if (dirPath.indexOf('.') === -1) {
dirPath = dirPath.substring(0, dirPath.lastIndexOf('/'));
} else if (dirPath.indexOf(".") === -1) {
dirPath = dirPath.substring(0, dirPath.lastIndexOf("/"));
// path
} else {
// strip any trailing slash
if (dirPath.match(/.*\/$/)) {
dirPath = dirPath.substring(0, dirPath.length - 2);
}
dirPath = dirPath.substring(0, dirPath.lastIndexOf('/'));
dirPath = dirPath.substring(0, dirPath.lastIndexOf("/"));
}
return dirPath;
@@ -660,7 +664,7 @@ module Harness {
export function _listFilesImpl(path: string, spec?: RegExp, options?: any) {
let response = Http.getFileFromServerSync(serverRoot + path);
if (response.status === 200) {
let results = response.responseText.split(',');
let results = response.responseText.split(",");
if (spec) {
return results.filter(file => spec.test(file));
} else {
@@ -668,12 +672,12 @@ module Harness {
}
}
else {
return [''];
return [""];
}
};
export let listFiles = Utils.memoize(_listFilesImpl);
export let log = console.log;
export let log = (s: string) => console.log(s);
export function readFile(file: string) {
let response = Http.getFileFromServerSync(serverRoot + file);
@@ -685,12 +689,11 @@ module Harness {
}
export function writeFile(path: string, contents: string) {
Http.writeToServerSync(serverRoot + path, 'WRITE', contents);
Http.writeToServerSync(serverRoot + path, "WRITE", contents);
}
}
}
export var IO: IO;
switch (Utils.getExecutionEnvironment()) {
case Utils.ExecutionEnvironment.CScript:
IO = IOImpl.CScript;
@@ -722,7 +725,7 @@ module Harness {
tcServicesFileName = "built/local/typescriptServices.js";
break;
default:
throw new Error('Unknown context');
throw new Error("Unknown context");
}
export let tcServicesFile = IO.readFile(tcServicesFileName);
@@ -745,12 +748,12 @@ module Harness {
public Write(str: string) {
// out of memory usage concerns avoid using + or += if we're going to do any manipulation of this string later
this.currentLine = [(this.currentLine || ''), str].join('');
this.currentLine = [(this.currentLine || ""), str].join("");
}
public WriteLine(str: string) {
// out of memory usage concerns avoid using + or += if we're going to do any manipulation of this string later
this.lines.push([(this.currentLine || ''), str].join(''));
this.lines.push([(this.currentLine || ""), str].join(""));
this.currentLine = undefined;
}
@@ -799,7 +802,7 @@ module Harness {
if (this.fileCollection.hasOwnProperty(p)) {
let current = <Harness.Compiler.WriterAggregator>this.fileCollection[p];
if (current.lines.length > 0) {
if (p.indexOf('.d.ts') !== -1) { current.lines.unshift(['////[', Path.getFileName(p), ']'].join('')); }
if (p.indexOf(".d.ts") !== -1) { current.lines.unshift(["////[", Path.getFileName(p), "]"].join("")); }
result.push({ fileName: p, file: this.fileCollection[p] });
}
}
@@ -828,12 +831,12 @@ module Harness {
const carriageReturnLineFeed = "\r\n";
const lineFeed = "\n";
export let defaultLibFileName = 'lib.d.ts';
export let defaultLibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + 'lib.core.d.ts'), /*languageVersion*/ ts.ScriptTarget.Latest);
export let defaultES6LibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + 'lib.core.es6.d.ts'), /*languageVersion*/ ts.ScriptTarget.Latest);
export let defaultLibFileName = "lib.d.ts";
export let defaultLibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + "lib.core.d.ts"), /*languageVersion*/ ts.ScriptTarget.Latest);
export let defaultES6LibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + "lib.core.es6.d.ts"), /*languageVersion*/ ts.ScriptTarget.Latest);
// Cache these between executions so we don't have to re-parse them for every test
export let fourslashFileName = 'fourslash.ts';
export let fourslashFileName = "fourslash.ts";
export let fourslashSourceFile: ts.SourceFile;
export function getCanonicalFileName(fileName: string): string {
@@ -865,6 +868,29 @@ module Harness {
}
};
inputFiles.forEach(register);
function getSourceFile(fn: string, languageVersion: ts.ScriptTarget) {
fn = ts.normalizePath(fn);
if (Object.prototype.hasOwnProperty.call(filemap, getCanonicalFileName(fn))) {
return filemap[getCanonicalFileName(fn)];
}
else if (currentDirectory) {
let canonicalAbsolutePath = getCanonicalFileName(ts.getNormalizedAbsolutePath(fn, currentDirectory));
return Object.prototype.hasOwnProperty.call(filemap, getCanonicalFileName(canonicalAbsolutePath)) ? filemap[canonicalAbsolutePath] : undefined;
}
else if (fn === fourslashFileName) {
let tsFn = "tests/cases/fourslash/" + fourslashFileName;
fourslashSourceFile = fourslashSourceFile || createSourceFileAndAssertInvariants(tsFn, Harness.IO.readFile(tsFn), scriptTarget);
return fourslashSourceFile;
}
else {
if (fn === defaultLibFileName) {
return languageVersion === ts.ScriptTarget.ES6 ? defaultES6LibSourceFile : defaultLibSourceFile;
}
// Don't throw here -- the compiler might be looking for a test that actually doesn't exist as part of the TC
return undefined;
}
}
let newLine =
newLineKind === ts.NewLineKind.CarriageReturnLineFeed ? carriageReturnLineFeed :
@@ -873,33 +899,14 @@ module Harness {
return {
getCurrentDirectory,
getSourceFile: (fn, languageVersion) => {
fn = ts.normalizePath(fn);
if (Object.prototype.hasOwnProperty.call(filemap, getCanonicalFileName(fn))) {
return filemap[getCanonicalFileName(fn)];
}
else if (currentDirectory) {
let canonicalAbsolutePath = getCanonicalFileName(ts.getNormalizedAbsolutePath(fn, currentDirectory));
return Object.prototype.hasOwnProperty.call(filemap, getCanonicalFileName(canonicalAbsolutePath)) ? filemap[canonicalAbsolutePath] : undefined;
}
else if (fn === fourslashFileName) {
let tsFn = 'tests/cases/fourslash/' + fourslashFileName;
fourslashSourceFile = fourslashSourceFile || createSourceFileAndAssertInvariants(tsFn, Harness.IO.readFile(tsFn), scriptTarget);
return fourslashSourceFile;
}
else {
if (fn === defaultLibFileName) {
return languageVersion === ts.ScriptTarget.ES6 ? defaultES6LibSourceFile : defaultLibSourceFile;
}
// Don't throw here -- the compiler might be looking for a test that actually doesn't exist as part of the TC
return undefined;
}
},
getSourceFile,
getDefaultLibFileName: options => defaultLibFileName,
writeFile,
getCanonicalFileName,
useCaseSensitiveFileNames: () => useCaseSensitiveFileNames,
getNewLine: () => newLine
getNewLine: () => newLine,
fileExists: fileName => getSourceFile(fileName, ts.ScriptTarget.ES5) !== undefined,
readFile: (fileName: string): string => { throw new Error("NotYetImplemented"); }
};
}
@@ -974,7 +981,7 @@ module Harness {
settingsCallback(null);
}
let newLine = '\r\n';
let newLine = "\r\n";
options.skipDefaultLibCheck = true;
// Files from built\local that are requested by test "@includeBuiltFiles" to be in the context.
@@ -1011,19 +1018,19 @@ module Harness {
// "fileName", "comments", "declaration", "module", "nolib", "sourcemap", "target", "out", "outdir", "noimplicitany", "noresolve"
case "module":
case "modulegentarget":
if (typeof setting.value === 'string') {
if (setting.value.toLowerCase() === 'amd') {
if (typeof setting.value === "string") {
if (setting.value.toLowerCase() === "amd") {
options.module = ts.ModuleKind.AMD;
} else if (setting.value.toLowerCase() === 'umd') {
} else if (setting.value.toLowerCase() === "umd") {
options.module = ts.ModuleKind.UMD;
} else if (setting.value.toLowerCase() === 'commonjs') {
} else if (setting.value.toLowerCase() === "commonjs") {
options.module = ts.ModuleKind.CommonJS;
} else if (setting.value.toLowerCase() === 'system') {
} else if (setting.value.toLowerCase() === "system") {
options.module = ts.ModuleKind.System;
} else if (setting.value.toLowerCase() === 'unspecified') {
} else if (setting.value.toLowerCase() === "unspecified") {
options.module = ts.ModuleKind.None;
} else {
throw new Error('Unknown module type ' + setting.value);
throw new Error("Unknown module type " + setting.value);
}
} else {
options.module = <any>setting.value;
@@ -1031,152 +1038,152 @@ module Harness {
break;
case "target":
case 'codegentarget':
if (typeof setting.value === 'string') {
if (setting.value.toLowerCase() === 'es3') {
case "codegentarget":
if (typeof setting.value === "string") {
if (setting.value.toLowerCase() === "es3") {
options.target = ts.ScriptTarget.ES3;
} else if (setting.value.toLowerCase() === 'es5') {
} else if (setting.value.toLowerCase() === "es5") {
options.target = ts.ScriptTarget.ES5;
} else if (setting.value.toLowerCase() === 'es6') {
} else if (setting.value.toLowerCase() === "es6") {
options.target = ts.ScriptTarget.ES6;
} else {
throw new Error('Unknown compile target ' + setting.value);
throw new Error("Unknown compile target " + setting.value);
}
} else {
options.target = <any>setting.value;
}
break;
case 'experimentaldecorators':
options.experimentalDecorators = setting.value === 'true';
case "experimentaldecorators":
options.experimentalDecorators = setting.value === "true";
break;
case 'emitdecoratormetadata':
options.emitDecoratorMetadata = setting.value === 'true';
case "emitdecoratormetadata":
options.emitDecoratorMetadata = setting.value === "true";
break;
case 'experimentalasyncfunctions':
options.experimentalAsyncFunctions = setting.value === 'true';
case "experimentalasyncfunctions":
options.experimentalAsyncFunctions = setting.value === "true";
break;
case 'noemithelpers':
options.noEmitHelpers = setting.value === 'true';
case "noemithelpers":
options.noEmitHelpers = setting.value === "true";
break;
case 'noemitonerror':
options.noEmitOnError = setting.value === 'true';
case "noemitonerror":
options.noEmitOnError = setting.value === "true";
break;
case 'noresolve':
options.noResolve = setting.value === 'true';
case "noresolve":
options.noResolve = setting.value === "true";
break;
case 'noimplicitany':
options.noImplicitAny = setting.value === 'true';
case "noimplicitany":
options.noImplicitAny = setting.value === "true";
break;
case 'nolib':
options.noLib = setting.value === 'true';
case "nolib":
options.noLib = setting.value === "true";
break;
case 'out':
case 'outfileoption':
case "out":
case "outfileoption":
options.out = setting.value;
break;
case 'outdiroption':
case 'outdir':
case "outdiroption":
case "outdir":
options.outDir = setting.value;
break;
case 'skipdefaultlibcheck':
case "skipdefaultlibcheck":
options.skipDefaultLibCheck = setting.value === "true";
break;
case 'sourceroot':
case "sourceroot":
options.sourceRoot = setting.value;
break;
case 'maproot':
case "maproot":
options.mapRoot = setting.value;
break;
case 'sourcemap':
options.sourceMap = setting.value === 'true';
case "sourcemap":
options.sourceMap = setting.value === "true";
break;
case 'declaration':
options.declaration = setting.value === 'true';
case "declaration":
options.declaration = setting.value === "true";
break;
case 'newline':
if (setting.value.toLowerCase() === 'crlf') {
case "newline":
if (setting.value.toLowerCase() === "crlf") {
options.newLine = ts.NewLineKind.CarriageReturnLineFeed;
}
else if (setting.value.toLowerCase() === 'lf') {
else if (setting.value.toLowerCase() === "lf") {
options.newLine = ts.NewLineKind.LineFeed;
}
else {
throw new Error('Unknown option for newLine: ' + setting.value);
throw new Error("Unknown option for newLine: " + setting.value);
}
break;
case 'comments':
options.removeComments = setting.value === 'false';
case "comments":
options.removeComments = setting.value === "false";
break;
case 'stripinternal':
options.stripInternal = setting.value === 'true';
case "stripinternal":
options.stripInternal = setting.value === "true";
case 'usecasesensitivefilenames':
useCaseSensitiveFileNames = setting.value === 'true';
case "usecasesensitivefilenames":
useCaseSensitiveFileNames = setting.value === "true";
break;
case 'filename':
case "filename":
// Not supported yet
break;
case 'emitbom':
options.emitBOM = setting.value === 'true';
case "emitbom":
options.emitBOM = setting.value === "true";
break;
case 'errortruncation':
options.noErrorTruncation = setting.value === 'false';
case "errortruncation":
options.noErrorTruncation = setting.value === "false";
break;
case 'preserveconstenums':
options.preserveConstEnums = setting.value === 'true';
case "preserveconstenums":
options.preserveConstEnums = setting.value === "true";
break;
case 'isolatedmodules':
options.isolatedModules = setting.value === 'true';
case "isolatedmodules":
options.isolatedModules = setting.value === "true";
break;
case 'suppressimplicitanyindexerrors':
options.suppressImplicitAnyIndexErrors = setting.value === 'true';
case "suppressimplicitanyindexerrors":
options.suppressImplicitAnyIndexErrors = setting.value === "true";
break;
case 'includebuiltfile':
case "includebuiltfile":
let builtFileName = libFolder + setting.value;
includeBuiltFiles.push({ unitName: builtFileName, content: normalizeLineEndings(IO.readFile(builtFileName), newLine) });
break;
case 'inlinesourcemap':
options.inlineSourceMap = setting.value === 'true';
case "inlinesourcemap":
options.inlineSourceMap = setting.value === "true";
break;
case 'inlinesources':
options.inlineSources = setting.value === 'true';
case "inlinesources":
options.inlineSources = setting.value === "true";
break;
case 'jsx':
options.jsx = setting.value.toLowerCase() === 'react' ? ts.JsxEmit.React :
setting.value.toLowerCase() === 'preserve' ? ts.JsxEmit.Preserve :
case "jsx":
options.jsx = setting.value.toLowerCase() === "react" ? ts.JsxEmit.React :
setting.value.toLowerCase() === "preserve" ? ts.JsxEmit.Preserve :
ts.JsxEmit.None;
break;
default:
throw new Error('Unsupported compiler setting ' + setting.flag);
throw new Error("Unsupported compiler setting " + setting.flag);
}
}
}
@@ -1189,7 +1196,7 @@ module Harness {
// Current directory is needed for rwcRunner to be able to use currentDirectory defined in json file
currentDirectory?: string) {
if (options.declaration && result.errors.length === 0 && result.declFilesCode.length !== result.files.length) {
throw new Error('There were no errors and declFiles generated did not match number of js files generated');
throw new Error("There were no errors and declFiles generated did not match number of js files generated");
}
let declInputFiles: { unitName: string; content: string }[] = [];
@@ -1250,8 +1257,8 @@ module Harness {
}
function normalizeLineEndings(text: string, lineEnding: string): string {
let normalized = text.replace(/\r\n?/g, '\n');
if (lineEnding !== '\n') {
let normalized = text.replace(/\r\n?/g, "\n");
if (lineEnding !== "\n") {
normalized = normalized.replace(/\n/g, lineEnding);
}
return normalized;
@@ -1282,10 +1289,10 @@ module Harness {
let message = ts.flattenDiagnosticMessageText(error.messageText, ts.sys.newLine);
let errLines = RunnerBase.removeFullPaths(message)
.split('\n')
.map(s => s.length > 0 && s.charAt(s.length - 1) === '\r' ? s.substr(0, s.length - 1) : s)
.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 => '!!! ' + ts.DiagnosticCategory[error.category].toLowerCase() + " TS" + error.code + ": " + s);
.map(s => "!!! " + ts.DiagnosticCategory[error.category].toLowerCase() + " TS" + error.code + ": " + s);
errLines.forEach(e => outputLines.push(e));
totalErrorsReported++;
@@ -1305,7 +1312,7 @@ module Harness {
// Header
outputLines.push('==== ' + inputFile.unitName + ' (' + fileErrors.length + ' errors) ====');
outputLines.push("==== " + inputFile.unitName + " (" + fileErrors.length + " errors) ====");
// Make sure we emit something for every error
let markedErrorCount = 0;
@@ -1314,13 +1321,13 @@ module Harness {
// we have to string-based splitting instead and try to figure out the delimiting chars
let lineStarts = ts.computeLineStarts(inputFile.content);
let lines = inputFile.content.split('\n');
let lines = inputFile.content.split("\n");
if (lines.length === 1) {
lines = lines[0].split("\r");
}
lines.forEach((line, lineIndex) => {
if (line.length > 0 && line.charAt(line.length - 1) === '\r') {
if (line.length > 0 && line.charAt(line.length - 1) === "\r") {
line = line.substr(0, line.length - 1);
}
@@ -1333,7 +1340,7 @@ module Harness {
nextLineStart = lineStarts[lineIndex + 1];
}
// Emit this line from the original file
outputLines.push(' ' + line);
outputLines.push(" " + line);
fileErrors.forEach(err => {
// Does any error start or continue on to this line? Emit squiggles
let end = ts.textSpanEnd(err);
@@ -1345,7 +1352,7 @@ module Harness {
// Calculate the start of the squiggle
let 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('~'));
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 > end) {
@@ -1360,7 +1367,7 @@ module Harness {
});
// Verify we didn't miss any errors in this file
assert.equal(markedErrorCount, fileErrors.length, 'count of errors in ' + inputFile.unitName);
assert.equal(markedErrorCount, fileErrors.length, "count of errors in " + inputFile.unitName);
});
let numLibraryDiagnostics = ts.countWhere(diagnostics, diagnostic => {
@@ -1373,10 +1380,10 @@ module Harness {
});
// Verify we didn't miss any errors in total
assert.equal(totalErrorsReported + numLibraryDiagnostics + numTest262HarnessDiagnostics, diagnostics.length, 'total number of errors');
assert.equal(totalErrorsReported + numLibraryDiagnostics + numTest262HarnessDiagnostics, diagnostics.length, "total number of errors");
return minimalDiagnosticsToString(diagnostics) +
ts.sys.newLine + ts.sys.newLine + outputLines.join('\r\n');
ts.sys.newLine + ts.sys.newLine + outputLines.join("\r\n");
}
export function collateOutputs(outputFiles: Harness.Compiler.GeneratedFile[]): string {
@@ -1384,15 +1391,15 @@ module Harness {
outputFiles.sort((a, b) => cleanName(a.fileName).localeCompare(cleanName(b.fileName)));
// Emit them
let result = '';
let result = "";
for (let outputFile of outputFiles) {
// Some extra spacing if this isn't the first file
if (result.length) {
result += '\r\n\r\n';
result += "\r\n\r\n";
}
// FileName header + content
result += '/*====== ' + outputFile.fileName + ' ======*/\r\n';
result += "/*====== " + outputFile.fileName + " ======*/\r\n";
result += outputFile.code;
}
@@ -1400,7 +1407,7 @@ module Harness {
return result;
function cleanName(fn: string) {
let lastSlash = ts.normalizeSlashes(fn).lastIndexOf('/');
let lastSlash = ts.normalizeSlashes(fn).lastIndexOf("/");
return fn.substr(lastSlash + 1).toLowerCase();
}
}
@@ -1418,7 +1425,7 @@ module Harness {
// This does not need to exist strictly speaking, but many tests will need to be updated if it's removed
export function compileString(code: string, unitName: string, callback: (result: CompilerResult) => void) {
// NEWTODO: Re-implement 'compileString'
throw new Error('compileString NYI');
throw new Error("compileString NYI");
}
export interface GeneratedFile {
@@ -1432,26 +1439,26 @@ module Harness {
}
export function isTS(fileName: string) {
return stringEndsWith(fileName, '.ts');
return stringEndsWith(fileName, ".ts");
}
export function isTSX(fileName: string) {
return stringEndsWith(fileName, '.tsx');
return stringEndsWith(fileName, ".tsx");
}
export function isDTS(fileName: string) {
return stringEndsWith(fileName, '.d.ts');
return stringEndsWith(fileName, ".d.ts");
}
export function isJS(fileName: string) {
return stringEndsWith(fileName, '.js');
return stringEndsWith(fileName, ".js");
}
export function isJSX(fileName: string) {
return stringEndsWith(fileName, '.jsx');
return stringEndsWith(fileName, ".jsx");
}
export function isJSMap(fileName: string) {
return stringEndsWith(fileName, '.js.map');
return stringEndsWith(fileName, ".js.map") || stringEndsWith(fileName, ".jsx.map");
}
/** Contains the code and errors of a compilation and some helper methods to check its status. */
@@ -1478,7 +1485,7 @@ module Harness {
this.sourceMaps.push(emittedFile);
}
else {
throw new Error('Unrecognized file extension for file ' + emittedFile.fileName);
throw new Error("Unrecognized file extension for file " + emittedFile.fileName);
}
});
@@ -1587,10 +1594,10 @@ module Harness {
// Subfile content line
// Append to the current subfile content, inserting a newline needed
if (currentFileContent === null) {
currentFileContent = '';
currentFileContent = "";
} else {
// End-of-line
currentFileContent = currentFileContent + '\n';
currentFileContent = currentFileContent + "\n";
}
currentFileContent = currentFileContent + line;
}
@@ -1601,7 +1608,7 @@ module Harness {
// EOF, push whatever remains
let newTestFile2 = {
content: currentFileContent || '',
content: currentFileContent || "",
name: currentFileName,
fileOptions: currentFileOptions,
originalFilePath: fileName,
@@ -1623,27 +1630,27 @@ module Harness {
export function localPath(fileName: string, baselineFolder?: string, subfolder?: string) {
if (baselineFolder === undefined) {
return baselinePath(fileName, 'local', 'tests/baselines', subfolder);
return baselinePath(fileName, "local", "tests/baselines", subfolder);
}
else {
return baselinePath(fileName, 'local', baselineFolder, subfolder);
return baselinePath(fileName, "local", baselineFolder, subfolder);
}
}
function referencePath(fileName: string, baselineFolder?: string, subfolder?: string) {
if (baselineFolder === undefined) {
return baselinePath(fileName, 'reference', 'tests/baselines', subfolder);
return baselinePath(fileName, "reference", "tests/baselines", subfolder);
}
else {
return baselinePath(fileName, 'reference', baselineFolder, subfolder);
return baselinePath(fileName, "reference", baselineFolder, subfolder);
}
}
function baselinePath(fileName: string, type: string, baselineFolder: string, subfolder?: string) {
if (subfolder !== undefined) {
return Harness.userSpecifiedRoot + baselineFolder + '/' + subfolder + '/' + type + '/' + fileName;
return Harness.userSpecifiedRoot + baselineFolder + "/" + subfolder + "/" + type + "/" + fileName;
} else {
return Harness.userSpecifiedRoot + baselineFolder + '/' + type + '/' + fileName;
return Harness.userSpecifiedRoot + baselineFolder + "/" + type + "/" + fileName;
}
}
@@ -1677,7 +1684,7 @@ module Harness {
let actual = generateContent();
if (actual === undefined) {
throw new Error('The generated content was "undefined". Return "null" if no baselining is required."');
throw new Error("The generated content was \"undefined\". Return \"null\" if no baselining is required.\"");
}
// Store the content in the 'local' folder so we
@@ -1700,10 +1707,10 @@ module Harness {
let refFileName = referencePath(relativeFileName, opts && opts.Baselinefolder, opts && opts.Subfolder);
if (actual === null) {
actual = '<no content>';
actual = "<no content>";
}
let expected = '<no content>';
let expected = "<no content>";
if (IO.fileExists(refFileName)) {
expected = IO.readFile(refFileName);
}
@@ -1712,10 +1719,10 @@ module Harness {
}
function writeComparison(expected: string, actual: string, relativeFileName: string, actualFileName: string, descriptionForDescribe: string) {
let encoded_actual = (new Buffer(actual)).toString('utf8');
let encoded_actual = (new Buffer(actual)).toString("utf8");
if (expected != encoded_actual) {
// Overwrite & issue error
let errMsg = 'The baseline file ' + relativeFileName + ' has changed';
let errMsg = "The baseline file " + relativeFileName + " has changed";
throw new Error(errMsg);
}
}
@@ -1744,7 +1751,7 @@ module Harness {
}
export function isLibraryFile(filePath: string): boolean {
return (Path.getFileName(filePath) === 'lib.d.ts') || (Path.getFileName(filePath) === 'lib.core.d.ts');
return (Path.getFileName(filePath) === "lib.d.ts") || (Path.getFileName(filePath) === "lib.core.d.ts");
}
export function isBuiltFile(filePath: string): boolean {
+43 -9
View File
@@ -1,7 +1,7 @@
/// <reference path='..\services\services.ts' />
/// <reference path='..\services\shims.ts' />
/// <reference path='..\server\client.ts' />
/// <reference path='harness.ts' />
/// <reference path="..\services\services.ts" />
/// <reference path="..\services\shims.ts" />
/// <reference path="..\server\client.ts" />
/// <reference path="harness.ts" />
module Harness.LanguageService {
export class ScriptInfo {
@@ -203,9 +203,35 @@ module Harness.LanguageService {
/// Shim adapter
class ShimLanguageServiceHost extends LanguageServiceAdapterHost implements ts.LanguageServiceShimHost, ts.CoreServicesShimHost {
private nativeHost: NativeLanguageServiceHost;
constructor(cancellationToken?: ts.HostCancellationToken, options?: ts.CompilerOptions) {
public getModuleResolutionsForFile: (fileName: string)=> string;
constructor(preprocessToResolve: boolean, cancellationToken?: ts.HostCancellationToken, options?: ts.CompilerOptions) {
super(cancellationToken, options);
this.nativeHost = new NativeLanguageServiceHost(cancellationToken, options);
if (preprocessToResolve) {
let compilerOptions = this.nativeHost.getCompilationSettings()
let moduleResolutionHost: ts.ModuleResolutionHost = {
fileExists: fileName => this.getScriptInfo(fileName) !== undefined,
readFile: fileName => {
let scriptInfo = this.getScriptInfo(fileName);
return scriptInfo && scriptInfo.content;
}
};
this.getModuleResolutionsForFile = (fileName) => {
let scriptInfo = this.getScriptInfo(fileName);
let preprocessInfo = ts.preProcessFile(scriptInfo.content, /*readImportFiles*/ true);
let imports: ts.Map<string> = {};
for (let module of preprocessInfo.importedFiles) {
let resolutionInfo = ts.resolveModuleName(module.fileName, fileName, compilerOptions, moduleResolutionHost);
if (resolutionInfo.resolvedFileName) {
imports[module.fileName] = resolutionInfo.resolvedFileName;
}
}
return JSON.stringify(imports);
}
}
}
getFilenames(): string[] { return this.nativeHost.getFilenames(); }
@@ -229,7 +255,11 @@ module Harness.LanguageService {
readDirectory(rootDir: string, extension: string): string {
throw new Error("NYI");
}
fileExists(fileName: string) { return this.getScriptInfo(fileName) !== undefined; }
readFile(fileName: string) {
let snapshot = this.nativeHost.getScriptSnapshot(fileName);
return snapshot && snapshot.getText(0, snapshot.getLength());
}
log(s: string): void { this.nativeHost.log(s); }
trace(s: string): void { this.nativeHost.trace(s); }
error(s: string): void { this.nativeHost.error(s); }
@@ -242,7 +272,7 @@ module Harness.LanguageService {
throw new Error("NYI");
}
getClassificationsForLine(text: string, lexState: ts.EndOfLineState, classifyKeywordsInGenerics?: boolean): ts.ClassificationResult {
let result = this.shim.getClassificationsForLine(text, lexState, classifyKeywordsInGenerics).split('\n');
let result = this.shim.getClassificationsForLine(text, lexState, classifyKeywordsInGenerics).split("\n");
let entries: ts.ClassificationInfo[] = [];
let i = 0;
let position = 0;
@@ -381,6 +411,9 @@ module Harness.LanguageService {
getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: ts.FormatCodeOptions): ts.TextChange[] {
return unwrapJSONCallResult(this.shim.getFormattingEditsAfterKeystroke(fileName, position, key, JSON.stringify(options)));
}
getDocCommentTemplateAtPosition(fileName: string, position: number): ts.TextInsertion {
return unwrapJSONCallResult(this.shim.getDocCommentTemplateAtPosition(fileName, position));
}
getEmitOutput(fileName: string): ts.EmitOutput {
return unwrapJSONCallResult(this.shim.getEmitOutput(fileName));
}
@@ -396,8 +429,8 @@ module Harness.LanguageService {
export class ShimLanugageServiceAdapter implements LanguageServiceAdapter {
private host: ShimLanguageServiceHost;
private factory: ts.TypeScriptServicesFactory;
constructor(cancellationToken?: ts.HostCancellationToken, options?: ts.CompilerOptions) {
this.host = new ShimLanguageServiceHost(cancellationToken, options);
constructor(preprocessToResolve: boolean, cancellationToken?: ts.HostCancellationToken, options?: ts.CompilerOptions) {
this.host = new ShimLanguageServiceHost(preprocessToResolve, cancellationToken, options);
this.factory = new TypeScript.Services.TypeScriptServicesFactory();
}
getHost() { return this.host; }
@@ -416,6 +449,7 @@ module Harness.LanguageService {
let convertResult: ts.PreProcessedFileInfo = {
referencedFiles: [],
importedFiles: [],
ambientExternalModules: [],
isLibFile: shimResult.isLibFile
};
+11 -11
View File
@@ -73,7 +73,7 @@ interface PlaybackControl {
module Playback {
let recordLog: IOLog = undefined;
let replayLog: IOLog = undefined;
let recordLogFileNameBase = '';
let recordLogFileNameBase = "";
interface Memoized<T> {
(s: string): T;
@@ -99,7 +99,7 @@ module Playback {
return {
timestamp: (new Date()).toString(),
arguments: [],
currentDirectory: '',
currentDirectory: "",
filesRead: [],
filesWritten: [],
filesDeleted: [],
@@ -110,7 +110,7 @@ module Playback {
dirExists: [],
dirsCreated: [],
pathsResolved: [],
executingPath: ''
executingPath: ""
};
}
@@ -170,7 +170,7 @@ module Playback {
if (defaultValue !== undefined) {
return defaultValue;
} else {
throw new Error('No matching result in log array for: ' + JSON.stringify(expectedFields));
throw new Error("No matching result in log array for: " + JSON.stringify(expectedFields));
}
}
return results[0].result;
@@ -195,7 +195,7 @@ module Playback {
}
// If we got here, we didn't find a match
if (defaultValue === undefined) {
throw new Error('No matching result in log array for path: ' + expectedPath);
throw new Error("No matching result in log array for path: " + expectedPath);
} else {
return defaultValue;
}
@@ -203,7 +203,7 @@ module Playback {
let pathEquivCache: any = {};
function pathsAreEquivalent(left: string, right: string, wrapper: { resolvePath(s: string): string }) {
let key = left + '-~~-' + right;
let key = left + "-~~-" + right;
function areSame(a: string, b: string) {
return ts.normalizeSlashes(a).toLowerCase() === ts.normalizeSlashes(b).toLowerCase();
}
@@ -233,14 +233,14 @@ module Playback {
wrapper.endRecord = () => {
if (recordLog !== undefined) {
let i = 0;
let fn = () => recordLogFileNameBase + i + '.json';
let fn = () => recordLogFileNameBase + i + ".json";
while (underlying.fileExists(fn())) i++;
underlying.writeFile(fn(), JSON.stringify(recordLog));
recordLog = undefined;
}
};
Object.defineProperty(wrapper, 'args', {
Object.defineProperty(wrapper, "args", {
get() {
if (replayLog !== undefined) {
return replayLog.arguments;
@@ -276,7 +276,7 @@ module Playback {
wrapper.getCurrentDirectory = () => {
if (replayLog !== undefined) {
return replayLog.currentDirectory || '';
return replayLog.currentDirectory || "";
} else if (recordLog !== undefined) {
return recordLog.currentDirectory = underlying.getCurrentDirectory();
} else {
@@ -286,7 +286,7 @@ module Playback {
wrapper.resolvePath = recordReplay(wrapper.resolvePath, underlying)(
(path) => callAndRecord(underlying.resolvePath(path), recordLog.pathsResolved, { path: path }),
memoize((path) => findResultByFields(replayLog.pathsResolved, { path: path }, !ts.isRootedDiskPath(ts.normalizeSlashes(path)) && replayLog.currentDirectory ? replayLog.currentDirectory + '/' + path : ts.normalizeSlashes(path))));
memoize((path) => findResultByFields(replayLog.pathsResolved, { path: path }, !ts.isRootedDiskPath(ts.normalizeSlashes(path)) && replayLog.currentDirectory ? replayLog.currentDirectory + "/" + path : ts.normalizeSlashes(path))));
wrapper.readFile = recordReplay(wrapper.readFile, underlying)(
(path) => {
@@ -299,7 +299,7 @@ module Playback {
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'));
(path, contents) => noOpReplay("writeFile"));
wrapper.exit = (exitCode) => {
if (recordLog !== undefined) {
+16 -14
View File
@@ -74,7 +74,7 @@ class ProjectRunner extends RunnerBase {
catch (e) {
assert(false, "Testcase: " + testCaseFileName + " does not contain valid json format: " + e.message);
}
let testCaseJustName = testCaseFileName.replace(/^.*[\\\/]/, '').replace(/\.json/, "");
let testCaseJustName = testCaseFileName.replace(/^.*[\\\/]/, "").replace(/\.json/, "");
function moduleNameToString(moduleKind: ts.ModuleKind) {
return moduleKind === ts.ModuleKind.AMD
@@ -191,7 +191,9 @@ class ProjectRunner extends RunnerBase {
getCurrentDirectory,
getCanonicalFileName: Harness.Compiler.getCanonicalFileName,
useCaseSensitiveFileNames: () => ts.sys.useCaseSensitiveFileNames,
getNewLine: () => ts.sys.newLine
getNewLine: () => ts.sys.newLine,
fileExists: fileName => getSourceFile(fileName, ts.ScriptTarget.ES5) !== undefined,
readFile: fileName => Harness.IO.readFile(fileName)
};
}
}
@@ -331,9 +333,9 @@ class ProjectRunner extends RunnerBase {
return Harness.Compiler.getErrorBaseline(inputFiles, compilerResult.errors);
}
let name = 'Compiling project for ' + testCase.scenario + ': testcase ' + testCaseFileName;
let name = "Compiling project for " + testCase.scenario + ": testcase " + testCaseFileName;
describe('Projects tests', () => {
describe("Projects tests", () => {
describe(name, () => {
function verifyCompilerResults(moduleKind: ts.ModuleKind) {
let compilerResult: BatchCompileProjectTestCaseResult;
@@ -367,27 +369,27 @@ class ProjectRunner extends RunnerBase {
compilerResult = batchCompilerProjectTestCase(moduleKind);
});
it('Resolution information of (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => {
Harness.Baseline.runBaseline('Resolution information of (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + '.json', () => {
it("Resolution information of (" + moduleNameToString(moduleKind) + "): " + testCaseFileName, () => {
Harness.Baseline.runBaseline("Resolution information of (" + moduleNameToString(compilerResult.moduleKind) + "): " + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + ".json", () => {
return JSON.stringify(getCompilerResolutionInfo(), undefined, " ");
});
});
it('Errors for (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => {
it("Errors for (" + moduleNameToString(moduleKind) + "): " + testCaseFileName, () => {
if (compilerResult.errors.length) {
Harness.Baseline.runBaseline('Errors for (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + '.errors.txt', () => {
Harness.Baseline.runBaseline("Errors for (" + moduleNameToString(compilerResult.moduleKind) + "): " + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + ".errors.txt", () => {
return getErrorsBaseline(compilerResult);
});
}
});
it('Baseline of emitted result (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => {
it("Baseline of emitted result (" + moduleNameToString(moduleKind) + "): " + testCaseFileName, () => {
if (testCase.baselineCheck) {
ts.forEach(compilerResult.outputFiles, outputFile => {
Harness.Baseline.runBaseline('Baseline of emitted result (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + outputFile.fileName, () => {
Harness.Baseline.runBaseline("Baseline of emitted result (" + moduleNameToString(compilerResult.moduleKind) + "): " + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + outputFile.fileName, () => {
try {
return ts.sys.readFile(getProjectOutputFolder(outputFile.fileName, compilerResult.moduleKind));
}
@@ -400,9 +402,9 @@ class ProjectRunner extends RunnerBase {
});
it('SourceMapRecord for (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => {
it("SourceMapRecord for (" + moduleNameToString(moduleKind) + "): " + testCaseFileName, () => {
if (compilerResult.sourceMapData) {
Harness.Baseline.runBaseline('SourceMapRecord for (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + '.sourcemap.txt', () => {
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.isJS(outputFile.emittedFileName)));
});
@@ -411,11 +413,11 @@ class ProjectRunner extends RunnerBase {
// Verify that all the generated .d.ts files compile
it('Errors in generated Dts files for (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => {
it("Errors in generated Dts files for (" + moduleNameToString(moduleKind) + "): " + testCaseFileName, () => {
if (!compilerResult.errors.length && testCase.declaration) {
let dTsCompileResult = compileCompileDTsFiles(compilerResult);
if (dTsCompileResult.errors.length) {
Harness.Baseline.runBaseline('Errors in generated Dts files for (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + '.dts.errors.txt', () => {
Harness.Baseline.runBaseline("Errors in generated Dts files for (" + moduleNameToString(compilerResult.moduleKind) + "): " + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + ".dts.errors.txt", () => {
return getErrorsBaseline(dTsCompileResult);
});
}
+23 -19
View File
@@ -13,12 +13,12 @@
// limitations under the License.
//
/// <reference path='test262Runner.ts' />
/// <reference path='compilerRunner.ts' />
/// <reference path='fourslashRunner.ts' />
/// <reference path='projectsRunner.ts' />
/// <reference path='rwcRunner.ts' />
/// <reference path='harness.ts' />
/// <reference path="test262Runner.ts" />
/// <reference path="compilerRunner.ts" />
/// <reference path="fourslashRunner.ts" />
/// <reference path="projectsRunner.ts" />
/// <reference path="rwcRunner.ts" />
/// <reference path="harness.ts" />
let runners: RunnerBase[] = [];
let iterations: number = 1;
@@ -32,13 +32,13 @@ function runTests(runners: RunnerBase[]) {
}
// 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
let mytestconfig = 'mytest.config';
let testconfig = 'test.config';
let mytestconfig = "mytest.config";
let testconfig = "test.config";
let testConfigFile =
Harness.IO.fileExists(mytestconfig) ? Harness.IO.readFile(mytestconfig) :
(Harness.IO.fileExists(testconfig) ? Harness.IO.readFile(testconfig) : '');
(Harness.IO.fileExists(testconfig) ? Harness.IO.readFile(testconfig) : "");
if (testConfigFile !== '') {
if (testConfigFile !== "") {
let testConfig = JSON.parse(testConfigFile);
if (testConfig.light) {
Harness.lightMode = true;
@@ -51,33 +51,36 @@ if (testConfigFile !== '') {
}
switch (option) {
case 'compiler':
case "compiler":
runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance));
runners.push(new CompilerBaselineRunner(CompilerTestType.Regressions));
runners.push(new ProjectRunner());
break;
case 'conformance':
case "conformance":
runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance));
break;
case 'project':
case "project":
runners.push(new ProjectRunner());
break;
case 'fourslash':
case "fourslash":
runners.push(new FourSlashRunner(FourSlashTestType.Native));
break;
case 'fourslash-shims':
case "fourslash-shims":
runners.push(new FourSlashRunner(FourSlashTestType.Shims));
break;
case 'fourslash-shims-pp':
runners.push(new FourSlashRunner(FourSlashTestType.ShimsWithPreprocess));
break;
case 'fourslash-server':
runners.push(new FourSlashRunner(FourSlashTestType.Server));
break;
case 'fourslash-generated':
case "fourslash-generated":
runners.push(new GeneratedFourslashRunner(FourSlashTestType.Native));
break;
case 'rwc':
case "rwc":
runners.push(new RWCRunner());
break;
case 'test262':
case "test262":
runners.push(new Test262BaselineRunner());
break;
}
@@ -98,10 +101,11 @@ if (runners.length === 0) {
// language services
runners.push(new FourSlashRunner(FourSlashTestType.Native));
runners.push(new FourSlashRunner(FourSlashTestType.Shims));
runners.push(new FourSlashRunner(FourSlashTestType.ShimsWithPreprocess));
runners.push(new FourSlashRunner(FourSlashTestType.Server));
// runners.push(new GeneratedFourslashRunner());
}
ts.sys.newLine = '\r\n';
ts.sys.newLine = "\r\n";
runTests(runners);
+1 -1
View File
@@ -33,7 +33,7 @@ abstract class RunnerBase {
// when running in the browser the 'full path' is the host name, shows up in error baselines
let localHost = /http:\/localhost:\d+/g;
fixedPath = fixedPath.replace(localHost, '');
fixedPath = fixedPath.replace(localHost, "");
return fixedPath;
}
}
+22 -21
View File
@@ -1,7 +1,7 @@
/// <reference path='harness.ts'/>
/// <reference path='runnerbase.ts' />
/// <reference path='loggedIO.ts' />
/// <reference path='..\compiler\commandLineParser.ts'/>
/// <reference path="harness.ts"/>
/// <reference path="runnerbase.ts" />
/// <reference path="loggedIO.ts" />
/// <reference path="..\compiler\commandLineParser.ts"/>
module RWC {
function runWithIOLog(ioLog: IOLog, fn: () => void) {
@@ -26,8 +26,8 @@ module RWC {
let compilerResult: Harness.Compiler.CompilerResult;
let compilerOptions: ts.CompilerOptions;
let baselineOpts: Harness.Baseline.BaselineOptions = {
Subfolder: 'rwc',
Baselinefolder: 'internal/baselines'
Subfolder: "rwc",
Baselinefolder: "internal/baselines"
};
let baseName = /(.*)\/(.*).json/.exec(ts.normalizeSlashes(jsonPath))[2];
let currentDirectory: string;
@@ -49,7 +49,7 @@ module RWC {
useCustomLibraryFile = undefined;
});
it('can compile', () => {
it("can compile", () => {
let harnessCompiler = Harness.Compiler.getCompiler();
let opts: ts.ParsedCommandLine;
@@ -74,10 +74,11 @@ module RWC {
});
// Add files to compilation
let isInInputList = (resolvedPath: string) => (inputFile: { unitName: string; content: string; }) => inputFile.unitName === resolvedPath;
for (let fileRead of ioLog.filesRead) {
// Check if the file is already added into the set of input files.
var resolvedPath = ts.normalizeSlashes(ts.sys.resolvePath(fileRead.path));
let inInputList = ts.forEach(inputFiles, inputFile => inputFile.unitName === resolvedPath);
const resolvedPath = ts.normalizeSlashes(ts.sys.resolvePath(fileRead.path));
let inInputList = ts.forEach(inputFiles, isInInputList(resolvedPath));
if (!Harness.isLibraryFile(fileRead.path)) {
if (inInputList) {
@@ -130,14 +131,14 @@ module RWC {
});
it('has the expected emitted code', () => {
Harness.Baseline.runBaseline('has the expected emitted code', baseName + '.output.js', () => {
it("has the expected emitted code", () => {
Harness.Baseline.runBaseline("has the expected emitted code", baseName + ".output.js", () => {
return Harness.Compiler.collateOutputs(compilerResult.files);
}, false, baselineOpts);
});
it('has the expected declaration file content', () => {
Harness.Baseline.runBaseline('has the expected declaration file content', baseName + '.d.ts', () => {
it("has the expected declaration file content", () => {
Harness.Baseline.runBaseline("has the expected declaration file content", baseName + ".d.ts", () => {
if (!compilerResult.declFilesCode.length) {
return null;
}
@@ -146,8 +147,8 @@ module RWC {
}, false, baselineOpts);
});
it('has the expected source maps', () => {
Harness.Baseline.runBaseline('has the expected source maps', baseName + '.map', () => {
it("has the expected source maps", () => {
Harness.Baseline.runBaseline("has the expected source maps", baseName + ".map", () => {
if (!compilerResult.sourceMaps.length) {
return null;
}
@@ -156,16 +157,16 @@ module RWC {
}, false, baselineOpts);
});
/*it('has correct source map record', () => {
/*it("has correct source map record", () => {
if (compilerOptions.sourceMap) {
Harness.Baseline.runBaseline('has correct source map record', baseName + '.sourcemap.txt', () => {
Harness.Baseline.runBaseline("has correct source map record", baseName + ".sourcemap.txt", () => {
return compilerResult.getSourceMapRecord();
}, false, baselineOpts);
}
});*/
it('has the expected errors', () => {
Harness.Baseline.runBaseline('has the expected errors', baseName + '.errors.txt', () => {
it("has the expected errors", () => {
Harness.Baseline.runBaseline("has the expected errors", baseName + ".errors.txt", () => {
if (compilerResult.errors.length === 0) {
return null;
}
@@ -176,9 +177,9 @@ module RWC {
// Ideally, a generated declaration file will have no errors. But we allow generated
// declaration file errors as part of the baseline.
it('has the expected errors in generated declaration files', () => {
it("has the expected errors in generated declaration files", () => {
if (compilerOptions.declaration && !compilerResult.errors.length) {
Harness.Baseline.runBaseline('has the expected errors in generated declaration files', baseName + '.dts.errors.txt', () => {
Harness.Baseline.runBaseline("has the expected errors in generated declaration files", baseName + ".dts.errors.txt", () => {
let declFileCompilationResult = Harness.Compiler.getCompiler().compileDeclarationFiles(inputFiles, otherFiles, compilerResult,
/*settingscallback*/ undefined, compilerOptions, currentDirectory);
if (declFileCompilationResult.declResult.errors.length === 0) {
+6 -6
View File
@@ -13,7 +13,7 @@
// limitations under the License.
//
///<reference path='harness.ts'/>
///<reference path="harness.ts"/>
module Harness.SourceMapRecoder {
@@ -50,11 +50,11 @@ module Harness.SourceMapRecoder {
return true;
}
if (sourceMapMappings.charAt(decodingIndex) == ',') {
if (sourceMapMappings.charAt(decodingIndex) == ",") {
return true;
}
if (sourceMapMappings.charAt(decodingIndex) == ';') {
if (sourceMapMappings.charAt(decodingIndex) == ";") {
return true;
}
@@ -117,7 +117,7 @@ module Harness.SourceMapRecoder {
}
while (decodingIndex < sourceMapMappings.length) {
if (sourceMapMappings.charAt(decodingIndex) == ';') {
if (sourceMapMappings.charAt(decodingIndex) == ";") {
// New line
decodeOfEncodedMapping.emittedLine++;
decodeOfEncodedMapping.emittedColumn = 1;
@@ -125,7 +125,7 @@ module Harness.SourceMapRecoder {
continue;
}
if (sourceMapMappings.charAt(decodingIndex) == ',') {
if (sourceMapMappings.charAt(decodingIndex) == ",") {
// Next entry is on same line - no action needed
decodingIndex++;
continue;
@@ -459,6 +459,6 @@ module Harness.SourceMapRecoder {
SourceMapSpanWriter.close(); // If the last spans werent emitted, emit them
}
sourceMapRecoder.Close();
return sourceMapRecoder.lines.join('\r\n');
return sourceMapRecoder.lines.join("\r\n");
}
}
+15 -15
View File
@@ -1,9 +1,9 @@
/// <reference path='harness.ts' />
/// <reference path='runnerbase.ts' />
/// <reference path="harness.ts" />
/// <reference path="runnerbase.ts" />
class Test262BaselineRunner extends RunnerBase {
private static basePath = 'internal/cases/test262';
private static helpersFilePath = 'tests/cases/test262-harness/helpers.d.ts';
private static basePath = "internal/cases/test262";
private static helpersFilePath = "tests/cases/test262-harness/helpers.d.ts";
private static helperFile = {
unitName: Test262BaselineRunner.helpersFilePath,
content: Harness.IO.readFile(Test262BaselineRunner.helpersFilePath)
@@ -15,8 +15,8 @@ class Test262BaselineRunner extends RunnerBase {
module: ts.ModuleKind.CommonJS
};
private static baselineOptions: Harness.Baseline.BaselineOptions = {
Subfolder: 'test262',
Baselinefolder: 'internal/baselines'
Subfolder: "test262",
Baselinefolder: "internal/baselines"
};
private static getTestFilePath(filename: string): string {
@@ -24,7 +24,7 @@ class Test262BaselineRunner extends RunnerBase {
}
private runTest(filePath: string) {
describe('test262 test for ' + filePath, () => {
describe("test262 test for " + filePath, () => {
// Mocha holds onto the closure environment of the describe callback even after the test is done.
// Everything declared here should be cleared out in the "after" callback.
let testState: {
@@ -36,7 +36,7 @@ class Test262BaselineRunner extends RunnerBase {
before(() => {
let content = Harness.IO.readFile(filePath);
let testFilename = ts.removeFileExtension(filePath).replace(/\//g, '_') + ".test";
let testFilename = ts.removeFileExtension(filePath).replace(/\//g, "_") + ".test";
let testCaseContent = Harness.TestCaseParser.makeUnitsFromTest(content, testFilename);
let inputFiles = testCaseContent.testUnitData.map(unit => {
@@ -61,15 +61,15 @@ class Test262BaselineRunner extends RunnerBase {
testState = undefined;
});
it('has the expected emitted code', () => {
Harness.Baseline.runBaseline('has the expected emitted code', testState.filename + '.output.js', () => {
it("has the expected emitted code", () => {
Harness.Baseline.runBaseline("has the expected emitted code", testState.filename + ".output.js", () => {
let files = testState.compilerResult.files.filter(f => f.fileName !== Test262BaselineRunner.helpersFilePath);
return Harness.Compiler.collateOutputs(files);
}, false, Test262BaselineRunner.baselineOptions);
});
it('has the expected errors', () => {
Harness.Baseline.runBaseline('has the expected errors', testState.filename + '.errors.txt', () => {
it("has the expected errors", () => {
Harness.Baseline.runBaseline("has the expected errors", testState.filename + ".errors.txt", () => {
let errors = testState.compilerResult.errors;
if (errors.length === 0) {
return null;
@@ -79,13 +79,13 @@ class Test262BaselineRunner extends RunnerBase {
}, false, Test262BaselineRunner.baselineOptions);
});
it('satisfies inletiants', () => {
it("satisfies inletiants", () => {
let sourceFile = testState.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
Utils.assertInvariants(sourceFile, /*parent:*/ undefined);
});
it('has the expected AST', () => {
Harness.Baseline.runBaseline('has the expected AST', testState.filename + '.AST.txt', () => {
it("has the expected AST", () => {
Harness.Baseline.runBaseline("has the expected AST", testState.filename + ".AST.txt", () => {
let sourceFile = testState.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
return Utils.sourceFileToJSON(sourceFile);
}, false, Test262BaselineRunner.baselineOptions);
+1 -1
View File
@@ -71,4 +71,4 @@ class TypeWriterWalker {
symbol: symbolString
});
}
}
}
+4 -4
View File
@@ -324,9 +324,9 @@ interface String {
/**
* Replaces text in a string, using a regular expression or search string.
* @param searchValue A String object or string literal that represents the regular expression
* @param replaceValue A function that returns the replacement text.
* @param replacer A function that returns the replacement text.
*/
replace(searchValue: string, replaceValue: (substring: string, ...args: any[]) => string): string;
replace(searchValue: string, replacer: (substring: string, ...args: any[]) => string): string;
/**
* Replaces text in a string, using a regular expression or search string.
@@ -338,9 +338,9 @@ interface String {
/**
* Replaces text in a string, using a regular expression or search string.
* @param searchValue A Regular Expression object containing the regular expression pattern and applicable flags
* @param replaceValue A function that returns the replacement text.
* @param replacer A function that returns the replacement text.
*/
replace(searchValue: RegExp, replaceValue: (substring: string, ...args: any[]) => string): string;
replace(searchValue: RegExp, replacer: (substring: string, ...args: any[]) => string): string;
/**
* Finds the first substring match in a regular expression search.
+3 -3
View File
@@ -11962,7 +11962,7 @@ interface Window extends EventTarget, WindowTimers, WindowSessionStorage, Window
onvolumechange: (ev: Event) => any;
onwaiting: (ev: Event) => any;
opener: Window;
orientation: string;
orientation: string | number;
outerHeight: number;
outerWidth: number;
pageXOffset: number;
@@ -12777,7 +12777,7 @@ declare var onunload: (ev: Event) => any;
declare var onvolumechange: (ev: Event) => any;
declare var onwaiting: (ev: Event) => any;
declare var opener: Window;
declare var orientation: string;
declare var orientation: string | number;
declare var outerHeight: number;
declare var outerWidth: number;
declare var pageXOffset: number;
@@ -12952,4 +12952,4 @@ declare function addEventListener(type: "unload", listener: (ev: Event) => any,
declare function addEventListener(type: "volumechange", listener: (ev: Event) => any, useCapture?: boolean): void;
declare function addEventListener(type: "waiting", listener: (ev: Event) => any, useCapture?: boolean): void;
declare function addEventListener(type: "wheel", listener: (ev: WheelEvent) => any, useCapture?: boolean): void;
declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
+90 -30
View File
@@ -87,8 +87,8 @@ interface SymbolConstructor {
split: symbol;
/**
* A method that converts an object to a corresponding primitive value.Called by the ToPrimitive
* abstract operation.
* A method that converts an object to a corresponding primitive value.
* Called by the ToPrimitive abstract operation.
*/
toPrimitive: symbol;
@@ -98,8 +98,8 @@ interface SymbolConstructor {
*/
toStringTag: symbol;
/**
* An Object whose own property names are property names that are excluded from the with
/**
* An Object whose own property names are property names that are excluded from the 'with'
* environment bindings of the associated objects.
*/
unscopables: symbol;
@@ -170,16 +170,19 @@ interface ObjectConstructor {
}
interface Function {
/**
* Returns a new function object that is identical to the argument object in all ways except
* for its identity and the value of its HomeObject internal slot.
*/
toMethod(newHome: Object): Function;
/**
* Returns the name of the function. Function names are read-only and can not be changed.
*/
name: string;
/**
* Determines whether the given value inherits from this function if this function was used
* as a constructor function.
*
* A constructor function can control which objects are recognized as its instances by
* 'instanceof' by overriding this method.
*/
[Symbol.hasInstance](value: any): boolean;
}
interface NumberConstructor {
@@ -257,6 +260,20 @@ interface Array<T> {
/** Iterator */
[Symbol.iterator](): IterableIterator<T>;
/**
* Returns an object whose properties have the value 'true'
* when they will be absent when used in a 'with' statement.
*/
[Symbol.unscopables](): {
copyWithin: boolean;
entries: boolean;
fill: boolean;
find: boolean;
findIndex: boolean;
keys: boolean;
values: boolean;
};
/**
* Returns an array of key, value pairs for every entry in the array
*/
@@ -619,37 +636,76 @@ interface Math {
[Symbol.toStringTag]: string;
}
interface Date {
/**
* Converts a Date object to a string.
*/
[Symbol.toPrimitive](hint: "default"): string;
/**
* Converts a Date object to a string.
*/
[Symbol.toPrimitive](hint: "string"): string;
/**
* Converts a Date object to a number.
*/
[Symbol.toPrimitive](hint: "number"): number;
/**
* Converts a Date object to a string or number.
*
* @param hint The strings "number", "string", or "default" to specify what primitive to return.
*
* @throws {TypeError} If 'hint' was given something other than "number", "string", or "default".
* @returns A number if 'hint' was "number", a string if 'hint' was "string" or "default".
*/
[Symbol.toPrimitive](hint: string): string | number;
}
interface RegExp {
/**
* Matches a string with a regular expression, and returns an array containing the results of
/**
* Matches a string with this regular expression, and returns an array containing the results of
* that search.
* @param string A string to search within.
*/
match(string: string): string[];
[Symbol.match](string: string): RegExpMatchArray;
/**
* Replaces text in a string, using a regular expression.
* @param searchValue A String object or string literal that represents the regular expression
* Replaces text in a string, using this regular expression.
* @param string A String object or string literal whose contents matching against
* this regular expression will be replaced
* @param replaceValue A String object or string literal containing the text to replace for every
* successful match of rgExp in stringObj.
* successful match of this regular expression.
*/
replace(string: string, replaceValue: string): string;
search(string: string): number;
[Symbol.replace](string: string, replaceValue: string): string;
/**
* Returns an Array object into which substrings of the result of converting string to a String
* have been stored. The substrings are determined by searching from left to right for matches
* of the this value regular expression; these occurrences are not part of any substring in the
* returned array, but serve to divide up the String value.
*
* If the regular expression that contains capturing parentheses, then each time separator is
* matched the results (including any undefined results) of the capturing parentheses are spliced.
* @param string string value to split
* @param limit if not undefined, the output array is truncated so that it contains no more
* than limit elements.
* Replaces text in a string, using this regular expression.
* @param string A String object or string literal whose contents matching against
* this regular expression will be replaced
* @param replacer A function that returns the replacement text.
*/
split(string: string, limit?: number): string[];
[Symbol.replace](string: string, replacer: (substring: string, ...args: any[]) => string): string;
/**
* Finds the position beginning first substring match in a regular expression search
* using this regular expression.
*
* @param string The string to search within.
*/
[Symbol.search](string: string): number;
/**
* Returns an array of substrings that were delimited by strings in the original input that
* match against this regular expression.
*
* If the regular expression contains capturing parentheses, then each time this
* regular expression matches, the results (including any undefined results) of the
* capturing parentheses are spliced.
*
* @param string string value to split
* @param limit if not undefined, the output array is truncated so that it contains no more
* than 'limit' elements.
*/
[Symbol.split](string: string, limit?: number): string[];
/**
* Returns a string indicating the flags of the regular expression in question. This field is read-only.
@@ -678,6 +734,10 @@ interface RegExp {
unicode: boolean;
}
interface RegExpConstructor {
[Symbol.species](): RegExpConstructor;
}
interface Map<K, V> {
clear(): void;
delete(key: K): boolean;
+1 -1
View File
@@ -806,7 +806,7 @@ interface EventListenerObject {
declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject;
interface ErrorEventHandler {
(event: Event | string, source?: string, fileno?: number, columnNumber?: number): void;
(message: string, filename?: string, lineno?: number, colno?: number, error?:Error): void;
}
interface PositionCallback {
(position: Position): void;
+32 -3
View File
@@ -183,7 +183,7 @@ namespace ts.server {
return {
configFileName: response.body.configFileName,
fileNameList: response.body.fileNameList
fileNames: response.body.fileNames
};
}
@@ -527,8 +527,33 @@ namespace ts.server {
});
}
getDocumentHighlights(fileName: string, position: number): DocumentHighlights[] {
throw new Error("Not Implemented Yet.");
getDocumentHighlights(fileName: string, position: number, filesToSearch: string[]): DocumentHighlights[] {
let { line, offset } = this.positionToOneBasedLineOffset(fileName, position);
let args: protocol.DocumentHighlightsRequestArgs = { file: fileName, line, offset, filesToSearch };
let request = this.processRequest<protocol.DocumentHighlightsRequest>(CommandNames.DocumentHighlights, args);
let response = this.processResponse<protocol.DocumentHighlightsResponse>(request);
let self = this;
return response.body.map(convertToDocumentHighlights);
function convertToDocumentHighlights(item: ts.server.protocol.DocumentHighlightsItem): ts.DocumentHighlights {
let { file, highlightSpans } = item;
return {
fileName: file,
highlightSpans: highlightSpans.map(convertHighlightSpan)
};
function convertHighlightSpan(span: ts.server.protocol.HighlightSpan): ts.HighlightSpan {
let start = self.lineOffsetToPosition(file, span.start);
let end = self.lineOffsetToPosition(file, span.end);
return {
textSpan: ts.createTextSpanFromBounds(start, end),
kind: span.kind
};
}
}
}
getOutliningSpans(fileName: string): OutliningSpan[] {
@@ -538,6 +563,10 @@ namespace ts.server {
getTodoComments(fileName: string, descriptors: TodoCommentDescriptor[]): TodoComment[] {
throw new Error("Not Implemented Yet.");
}
getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion {
throw new Error("Not Implemented Yet.");
}
getBraceMatchingAtPosition(fileName: string, position: number): TextSpan[] {
var lineOffset = this.positionToOneBasedLineOffset(fileName, position);
+71 -8
View File
@@ -78,15 +78,76 @@ namespace ts.server {
return this.snap().getChangeRange(oldSnapshot);
}
}
interface TimestampedResolvedModule extends ResolvedModule {
lastCheckTime: number;
}
export class LSHost implements ts.LanguageServiceHost {
ls: ts.LanguageService = null;
compilationSettings: ts.CompilerOptions;
filenameToScript: ts.Map<ScriptInfo> = {};
roots: ScriptInfo[] = [];
private resolvedModuleNames: ts.FileMap<Map<TimestampedResolvedModule>>;
private moduleResolutionHost: ts.ModuleResolutionHost;
constructor(public host: ServerHost, public project: Project) {
this.resolvedModuleNames = ts.createFileMap<Map<TimestampedResolvedModule>>(ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames))
this.moduleResolutionHost = {
fileExists: fileName => this.fileExists(fileName),
readFile: fileName => this.host.readFile(fileName)
}
}
resolveModuleNames(moduleNames: string[], containingFile: string): string[] {
let currentResolutionsInFile = this.resolvedModuleNames.get(containingFile);
let newResolutions: Map<TimestampedResolvedModule> = {};
let resolvedFileNames: string[] = [];
let compilerOptions = this.getCompilationSettings();
for (let moduleName of moduleNames) {
// check if this is a duplicate entry in the list
let resolution = lookUp(newResolutions, moduleName);
if (!resolution) {
let existingResolution = currentResolutionsInFile && ts.lookUp(currentResolutionsInFile, moduleName);
if (moduleResolutionIsValid(existingResolution)) {
// ok, it is safe to use existing module resolution results
resolution = existingResolution;
}
else {
resolution = <TimestampedResolvedModule>resolveModuleName(moduleName, containingFile, compilerOptions, this.moduleResolutionHost);
resolution.lastCheckTime = Date.now();
newResolutions[moduleName] = resolution;
}
}
ts.Debug.assert(resolution !== undefined);
resolvedFileNames.push(resolution.resolvedFileName);
}
// replace old results with a new one
this.resolvedModuleNames.set(containingFile, newResolutions);
return resolvedFileNames;
function moduleResolutionIsValid(resolution: TimestampedResolvedModule): boolean {
if (!resolution) {
return false;
}
if (resolution.resolvedFileName) {
// TODO: consider checking failedLookupLocations
// TODO: use lastCheckTime to track expiration for module name resolution
return true;
}
// consider situation if we have no candidate locations as valid resolution.
// after all there is no point to invalidate it if we have no idea where to look for the module.
return resolution.failedLookupLocations.length === 0;
}
}
getDefaultLibFileName() {
var nodeModuleBinDir = ts.getDirectoryPath(ts.normalizePath(this.host.getExecutingFilePath()));
@@ -102,6 +163,8 @@ namespace ts.server {
setCompilationSettings(opt: ts.CompilerOptions) {
this.compilationSettings = opt;
// conservatively assume that changing compiler options might affect module resolution strategy
this.resolvedModuleNames.clear();
}
lineAffectsRefs(filename: string, line: number) {
@@ -137,6 +200,7 @@ namespace ts.server {
removeReferencedFile(info: ScriptInfo) {
if (!info.isOpen) {
this.filenameToScript[info.fileName] = undefined;
this.resolvedModuleNames.remove(info.fileName);
}
}
@@ -313,7 +377,7 @@ namespace ts.server {
return this.projectService.openFile(filename, false);
}
getFileNameList() {
getFileNames() {
let sourceFiles = this.program.getSourceFiles();
return sourceFiles.map(sourceFile => sourceFile.fileName);
}
@@ -555,7 +619,7 @@ namespace ts.server {
project.projectFileWatcher.close();
this.configuredProjects = copyListRemovingItem(project, this.configuredProjects);
let fileNames = project.getFileNameList();
let fileNames = project.getFileNames();
for (let fileName of fileNames) {
this.getScriptInfo(fileName).defaultProject = undefined;
}
@@ -853,9 +917,6 @@ namespace ts.server {
} else {
this.log("no config file");
}
if (configFileName) {
configFileName = getAbsolutePath(configFileName, searchPath);
}
if (configFileName) {
let project = this.findConfiguredProjectByConfigFile(configFileName);
if (!project) {
@@ -966,7 +1027,8 @@ namespace ts.server {
configFilename = ts.normalizePath(configFilename);
// file references will be relative to dirPath (or absolute)
var dirPath = ts.getDirectoryPath(configFilename);
var rawConfig: { config?: ProjectOptions; error?: Diagnostic; } = ts.readConfigFile(configFilename);
var contents = this.host.readFile(configFilename)
var rawConfig: { config?: ProjectOptions; error?: Diagnostic; } = ts.parseConfigFileText(configFilename, contents);
if (rawConfig.error) {
return { succeeded: false, error: rawConfig.error };
}
@@ -1106,6 +1168,7 @@ namespace ts.server {
InsertSpaceAfterKeywordsInControlFlowStatements: true,
InsertSpaceAfterFunctionKeywordForAnonymousFunctions: false,
InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false,
InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false,
PlaceOpenBraceOnNewLineForFunctions: false,
PlaceOpenBraceOnNewLineForControlBlocks: false,
}
File diff suppressed because it is too large Load Diff
+7 -2
View File
@@ -123,9 +123,14 @@ declare module NodeJS {
export interface ReadWriteStream extends ReadableStream, WritableStream { }
interface WindowSize {
columns: number;
rows: number;
}
export interface Process extends EventEmitter {
stdout: WritableStream;
stderr: WritableStream;
stdout: WritableStream & WindowSize;
stderr: WritableStream & WindowSize;
stdin: ReadableStream;
argv: string[];
execPath: string;
+69 -1
View File
@@ -116,7 +116,7 @@ declare namespace ts.server.protocol {
/**
* The list of normalized file name in the project, including 'lib.d.ts'
*/
fileNameList?: string[];
fileNames?: string[];
}
/**
@@ -156,6 +156,17 @@ declare namespace ts.server.protocol {
arguments: FileLocationRequestArgs;
}
/**
* Arguments in document highlight request; include: filesToSearch, file,
* line, offset.
*/
export interface DocumentHighlightsRequestArgs extends FileLocationRequestArgs {
/**
* List of files to search for document highlights.
*/
filesToSearch: string[];
}
/**
* Go to definition request; value of command field is
* "definition". Return response giving the file locations that
@@ -238,6 +249,35 @@ declare namespace ts.server.protocol {
body?: OccurrencesResponseItem[];
}
/**
* Get document highlights request; value of command field is
* "documentHighlights". Return response giving spans that are relevant
* in the file at a given line and column.
*/
export interface DocumentHighlightsRequest extends FileLocationRequest {
arguments: DocumentHighlightsRequestArgs
}
export interface HighlightSpan extends TextSpan {
kind: string
}
export interface DocumentHighlightsItem {
/**
* File containing highlight spans.
*/
file: string,
/**
* Spans to highlight in file.
*/
highlightSpans: HighlightSpan[];
}
export interface DocumentHighlightsResponse extends Response {
body?: DocumentHighlightsItem[];
}
/**
* Find references request; value of command field is
* "references". Return response giving the file locations that
@@ -412,6 +452,9 @@ declare namespace ts.server.protocol {
/** Defines space handling after opening and before closing non empty parenthesis. Default value is false. */
insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis?: boolean;
/** Defines space handling after opening and before closing non empty brackets. Default value is false. */
insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets?: boolean;
/** Defines whether an open brace is put onto a new line for functions or not. Default value is false. */
placeOpenBraceOnNewLineForFunctions?: boolean;
@@ -854,6 +897,31 @@ declare namespace ts.server.protocol {
export interface SignatureHelpResponse extends Response {
body?: SignatureHelpItems;
}
/**
* Arguments for GeterrForProject request.
*/
export interface GeterrForProjectRequestArgs {
/**
* the file requesting project error list
*/
file: string;
/**
* Delay in milliseconds to wait before starting to compute
* errors for the files in the file list
*/
delay: number;
}
/**
* GeterrForProjectRequest request; value of command field is
* "geterrForProject". It works similarly with 'Geterr', only
* it request for every file in this project.
*/
export interface GeterrForProjectRequest extends Request {
arguments: GeterrForProjectRequestArgs
}
/**
* Arguments for geterr messages.
+97 -5
View File
@@ -86,9 +86,11 @@ namespace ts.server {
export const Format = "format";
export const Formatonkey = "formatonkey";
export const Geterr = "geterr";
export const GeterrForProject = "geterrForProject";
export const NavBar = "navbar";
export const Navto = "navto";
export const Occurrences = "occurrences";
export const DocumentHighlights = "documentHighlights";
export const Open = "open";
export const Quickinfo = "quickinfo";
export const References = "references";
@@ -234,7 +236,7 @@ namespace ts.server {
}
private updateErrorCheck(checkList: PendingErrorCheck[], seq: number,
matchSeq: (seq: number) => boolean, ms = 1500, followMs = 200) {
matchSeq: (seq: number) => boolean, ms = 1500, followMs = 200, requireOpen = true) {
if (followMs > ms) {
followMs = ms;
}
@@ -249,7 +251,7 @@ namespace ts.server {
var checkOne = () => {
if (matchSeq(seq)) {
var checkSpec = checkList[index++];
if (checkSpec.project.getSourceFileFromName(checkSpec.fileName, true)) {
if (checkSpec.project.getSourceFileFromName(checkSpec.fileName, requireOpen)) {
this.syntacticCheck(checkSpec.fileName, checkSpec.project);
this.immediateId = setImmediate(() => {
this.semanticCheck(checkSpec.fileName, checkSpec.project);
@@ -313,7 +315,7 @@ namespace ts.server {
}));
}
private getOccurrences(line: number, offset: number, fileName: string): protocol.OccurrencesResponseItem[]{
private getOccurrences(line: number, offset: number, fileName: string): protocol.OccurrencesResponseItem[] {
fileName = ts.normalizePath(fileName);
let project = this.projectService.getProjectForFile(fileName);
@@ -343,6 +345,42 @@ namespace ts.server {
});
}
private getDocumentHighlights(line: number, offset: number, fileName: string, filesToSearch: string[]): protocol.DocumentHighlightsItem[] {
fileName = ts.normalizePath(fileName);
let project = this.projectService.getProjectForFile(fileName);
if (!project) {
throw Errors.NoProject;
}
let { compilerService } = project;
let position = compilerService.host.lineOffsetToPosition(fileName, line, offset);
let documentHighlights = compilerService.languageService.getDocumentHighlights(fileName, position, filesToSearch);
if (!documentHighlights) {
return undefined;
}
return documentHighlights.map(convertToDocumentHighlightsItem);
function convertToDocumentHighlightsItem(documentHighlights: ts.DocumentHighlights): ts.server.protocol.DocumentHighlightsItem {
let { fileName, highlightSpans } = documentHighlights;
return {
file: fileName,
highlightSpans: highlightSpans.map(convertHighlightSpan)
};
function convertHighlightSpan(highlightSpan: ts.HighlightSpan): ts.server.protocol.HighlightSpan {
let { textSpan, kind } = highlightSpan;
let start = compilerService.host.positionToLineOffset(fileName, textSpan.start);
let end = compilerService.host.positionToLineOffset(fileName, ts.textSpanEnd(textSpan));
return { start, end, kind };
}
}
}
private getProjectInfo(fileName: string, needFileNameList: boolean): protocol.ProjectInfo {
fileName = ts.normalizePath(fileName)
let project = this.projectService.getProjectForFile(fileName)
@@ -352,7 +390,7 @@ namespace ts.server {
}
if (needFileNameList) {
projectInfo.fileNameList = project.getFileNameList();
projectInfo.fileNames = project.getFileNames();
}
return projectInfo;
@@ -836,7 +874,53 @@ namespace ts.server {
}));
}
public exit() {
getDiagnosticsForProject(delay: number, fileName: string) {
let { configFileName, fileNames: fileNamesInProject } = this.getProjectInfo(fileName, true);
// No need to analyze lib.d.ts
fileNamesInProject = fileNamesInProject.filter((value, index, array) => value.indexOf("lib.d.ts") < 0);
// Sort the file name list to make the recently touched files come first
let highPriorityFiles: string[] = [];
let mediumPriorityFiles: string[] = [];
let lowPriorityFiles: string[] = [];
let veryLowPriorityFiles: string[] = [];
let normalizedFileName = ts.normalizePath(fileName);
let project = this.projectService.getProjectForFile(normalizedFileName);
for (let fileNameInProject of fileNamesInProject) {
if (this.getCanonicalFileName(fileNameInProject) == this.getCanonicalFileName(fileName))
highPriorityFiles.push(fileNameInProject);
else {
let info = this.projectService.getScriptInfo(fileNameInProject);
if (!info.isOpen) {
if (fileNameInProject.indexOf(".d.ts") > 0)
veryLowPriorityFiles.push(fileNameInProject);
else
lowPriorityFiles.push(fileNameInProject);
}
else
mediumPriorityFiles.push(fileNameInProject);
}
}
fileNamesInProject = highPriorityFiles.concat(mediumPriorityFiles).concat(lowPriorityFiles).concat(veryLowPriorityFiles);
if (fileNamesInProject.length > 0) {
let checkList = fileNamesInProject.map<PendingErrorCheck>((fileName: string) => {
let normalizedFileName = ts.normalizePath(fileName);
return { fileName: normalizedFileName, project };
});
// Project level error analysis runs on background files too, therefore
// doesn't require the file to be opened
this.updateErrorCheck(checkList, this.changeSeq, (n) => n == this.changeSeq, delay, 200, /*requireOpen*/ false);
}
}
getCanonicalFileName(fileName: string) {
let name = this.host.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
return ts.normalizePath(name);
}
exit() {
}
private handlers : Map<(request: protocol.Request) => {response?: any, responseRequired?: boolean}> = {
@@ -894,6 +978,10 @@ namespace ts.server {
var geterrArgs = <protocol.GeterrRequestArgs>request.arguments;
return {response: this.getDiagnostics(geterrArgs.delay, geterrArgs.files), responseRequired: false};
},
[CommandNames.GeterrForProject]: (request: protocol.Request) => {
let { file, delay } = <protocol.GeterrForProjectRequestArgs>request.arguments;
return {response: this.getDiagnosticsForProject(delay, file), responseRequired: false};
},
[CommandNames.Change]: (request: protocol.Request) => {
var changeArgs = <protocol.ChangeRequestArgs>request.arguments;
this.change(changeArgs.line, changeArgs.offset, changeArgs.endLine, changeArgs.endOffset,
@@ -937,6 +1025,10 @@ namespace ts.server {
var { line, offset, file: fileName } = <protocol.FileLocationRequestArgs>request.arguments;
return {response: this.getOccurrences(line, offset, fileName), responseRequired: true};
},
[CommandNames.DocumentHighlights]: (request: protocol.Request) => {
var { line, offset, file: fileName, filesToSearch } = <protocol.DocumentHighlightsRequestArgs>request.arguments;
return {response: this.getDocumentHighlights(line, offset, fileName, filesToSearch), responseRequired: true};
},
[CommandNames.ProjectInfo]: (request: protocol.Request) => {
var { file, needFileNameList } = <protocol.ProjectInfoRequestArgs>request.arguments;
return {response: this.getProjectInfo(file, needFileNameList), responseRequired: true};
+43 -19
View File
@@ -39,12 +39,12 @@ namespace ts.formatting {
public SpaceBetweenCloseBraceAndWhile: Rule;
public NoSpaceAfterCloseBrace: Rule;
// No space for indexer and dot
// No space for dot
public NoSpaceBeforeDot: Rule;
public NoSpaceAfterDot: Rule;
// No space before and after indexer
public NoSpaceBeforeOpenBracket: Rule;
public NoSpaceAfterOpenBracket: Rule;
public NoSpaceBeforeCloseBracket: Rule;
public NoSpaceAfterCloseBracket: Rule;
// Insert a space after { and before } in single-line contexts, but remove space from empty object literals {}.
@@ -135,6 +135,7 @@ namespace ts.formatting {
public NoSpaceAfterOpenAngularBracket: Rule;
public NoSpaceBeforeCloseAngularBracket: Rule;
public NoSpaceAfterCloseAngularBracket: Rule;
public NoSpaceAfterTypeAssertion: Rule;
// Remove spaces in empty interface literals. e.g.: x: {}
public NoSpaceBetweenEmptyInterfaceBraceBrackets: Rule;
@@ -190,6 +191,13 @@ namespace ts.formatting {
public NoSpaceAfterOpenParen: Rule;
public NoSpaceBeforeCloseParen: Rule;
// Insert space after opening and before closing nonempty brackets
public SpaceAfterOpenBracket: Rule;
public SpaceBeforeCloseBracket: Rule;
public NoSpaceBetweenBrackets: Rule;
public NoSpaceAfterOpenBracket: Rule;
public NoSpaceBeforeCloseBracket: Rule;
// Insert space after function keyword for anonymous functions
public SpaceAfterAnonymousFunctionKeyword: Rule;
public NoSpaceAfterAnonymousFunctionKeyword: Rule;
@@ -231,13 +239,13 @@ namespace ts.formatting {
this.SpaceBetweenCloseBraceAndWhile = new Rule(RuleDescriptor.create1(SyntaxKind.CloseBraceToken, SyntaxKind.WhileKeyword), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Space));
this.NoSpaceAfterCloseBrace = new Rule(RuleDescriptor.create3(SyntaxKind.CloseBraceToken, Shared.TokenRange.FromTokens([SyntaxKind.CloseParenToken, SyntaxKind.CloseBracketToken, SyntaxKind.CommaToken, SyntaxKind.SemicolonToken])), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete));
// No space for indexer and dot
// No space for dot
this.NoSpaceBeforeDot = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.DotToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete));
this.NoSpaceAfterDot = new Rule(RuleDescriptor.create3(SyntaxKind.DotToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete));
// No space before and after indexer
this.NoSpaceBeforeOpenBracket = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.OpenBracketToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete));
this.NoSpaceAfterOpenBracket = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBracketToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete));
this.NoSpaceBeforeCloseBracket = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBracketToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete));
this.NoSpaceAfterCloseBracket = new Rule(RuleDescriptor.create3(SyntaxKind.CloseBracketToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsNotBeforeBlockInFunctionDeclarationContext), RuleAction.Delete));
this.NoSpaceAfterCloseBracket = new Rule(RuleDescriptor.create3(SyntaxKind.CloseBracketToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsNotBeforeBlockInFunctionDeclarationContext ), RuleAction.Delete));
// Place a space before open brace in a function declaration
this.FunctionOpenBraceLeftTokenRange = Shared.TokenRange.AnyIncludingMultilineComments;
@@ -331,12 +339,13 @@ namespace ts.formatting {
this.NoSpaceAfterEllipsis = new Rule(RuleDescriptor.create1(SyntaxKind.DotDotDotToken, SyntaxKind.Identifier), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete));
this.NoSpaceAfterOptionalParameters = new Rule(RuleDescriptor.create3(SyntaxKind.QuestionToken, Shared.TokenRange.FromTokens([SyntaxKind.CloseParenToken, SyntaxKind.CommaToken])), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsNotBinaryOpContext), RuleAction.Delete));
// generics
this.NoSpaceBeforeOpenAngularBracket = new Rule(RuleDescriptor.create2(Shared.TokenRange.TypeNames, SyntaxKind.LessThanToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsTypeArgumentOrParameterContext), RuleAction.Delete));
this.NoSpaceBetweenCloseParenAndAngularBracket = new Rule(RuleDescriptor.create1(SyntaxKind.CloseParenToken, SyntaxKind.LessThanToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsTypeArgumentOrParameterContext), RuleAction.Delete));
this.NoSpaceAfterOpenAngularBracket = new Rule(RuleDescriptor.create3(SyntaxKind.LessThanToken, Shared.TokenRange.TypeNames), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsTypeArgumentOrParameterContext), RuleAction.Delete));
this.NoSpaceBeforeCloseAngularBracket = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.GreaterThanToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsTypeArgumentOrParameterContext), RuleAction.Delete));
this.NoSpaceAfterCloseAngularBracket = new Rule(RuleDescriptor.create3(SyntaxKind.GreaterThanToken, Shared.TokenRange.FromTokens([SyntaxKind.OpenParenToken, SyntaxKind.OpenBracketToken, SyntaxKind.GreaterThanToken, SyntaxKind.CommaToken])), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsTypeArgumentOrParameterContext), RuleAction.Delete));
// generics and type assertions
this.NoSpaceBeforeOpenAngularBracket = new Rule(RuleDescriptor.create2(Shared.TokenRange.TypeNames, SyntaxKind.LessThanToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsTypeArgumentOrParameterOrAssertionContext), RuleAction.Delete));
this.NoSpaceBetweenCloseParenAndAngularBracket = new Rule(RuleDescriptor.create1(SyntaxKind.CloseParenToken, SyntaxKind.LessThanToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsTypeArgumentOrParameterOrAssertionContext), RuleAction.Delete));
this.NoSpaceAfterOpenAngularBracket = new Rule(RuleDescriptor.create3(SyntaxKind.LessThanToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsTypeArgumentOrParameterOrAssertionContext), RuleAction.Delete));
this.NoSpaceBeforeCloseAngularBracket = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.GreaterThanToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsTypeArgumentOrParameterOrAssertionContext), RuleAction.Delete));
this.NoSpaceAfterCloseAngularBracket = new Rule(RuleDescriptor.create3(SyntaxKind.GreaterThanToken, Shared.TokenRange.FromTokens([SyntaxKind.OpenParenToken, SyntaxKind.OpenBracketToken, SyntaxKind.GreaterThanToken, SyntaxKind.CommaToken])), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsTypeArgumentOrParameterOrAssertionContext), RuleAction.Delete));
this.NoSpaceAfterTypeAssertion = new Rule(RuleDescriptor.create3(SyntaxKind.GreaterThanToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsTypeAssertionContext), RuleAction.Delete));
// Remove spaces in empty interface literals. e.g.: x: {}
this.NoSpaceBetweenEmptyInterfaceBraceBrackets = new Rule(RuleDescriptor.create1(SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsObjectTypeContext), RuleAction.Delete));
@@ -391,6 +400,7 @@ namespace ts.formatting {
this.NoSpaceAfterOpenAngularBracket,
this.NoSpaceBeforeCloseAngularBracket,
this.NoSpaceAfterCloseAngularBracket,
this.NoSpaceAfterTypeAssertion,
this.SpaceBeforeAt,
this.NoSpaceAfterAt,
this.SpaceAfterDecorator,
@@ -402,8 +412,8 @@ namespace ts.formatting {
this.NoSpaceBeforeSemicolon,
this.SpaceBeforeOpenBraceInControl, this.SpaceBeforeOpenBraceInFunction, this.SpaceBeforeOpenBraceInTypeScriptDeclWithBlock,
this.NoSpaceBeforeComma,
this.NoSpaceBeforeOpenBracket, this.NoSpaceAfterOpenBracket,
this.NoSpaceBeforeCloseBracket, this.NoSpaceAfterCloseBracket,
this.NoSpaceBeforeOpenBracket,
this.NoSpaceAfterCloseBracket,
this.SpaceAfterSemicolon,
this.NoSpaceBeforeOpenParenInFuncDecl,
this.SpaceBetweenStatements, this.SpaceAfterTryFinally
@@ -448,6 +458,13 @@ namespace ts.formatting {
this.NoSpaceAfterOpenParen = new Rule(RuleDescriptor.create3(SyntaxKind.OpenParenToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete));
this.NoSpaceBeforeCloseParen = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete));
// Insert space after opening and before closing nonempty brackets
this.SpaceAfterOpenBracket = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBracketToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Space));
this.SpaceBeforeCloseBracket = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBracketToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Space));
this.NoSpaceBetweenBrackets = new Rule(RuleDescriptor.create1(SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete));
this.NoSpaceAfterOpenBracket = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBracketToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete));
this.NoSpaceBeforeCloseBracket = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBracketToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete));
// Insert space after function keyword for anonymous functions
this.SpaceAfterAnonymousFunctionKeyword = new Rule(RuleDescriptor.create1(SyntaxKind.FunctionKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsFunctionDeclContext), RuleAction.Space));
this.NoSpaceAfterAnonymousFunctionKeyword = new Rule(RuleDescriptor.create1(SyntaxKind.FunctionKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsFunctionDeclContext), RuleAction.Delete));
@@ -704,13 +721,15 @@ namespace ts.formatting {
return context.contextNode.kind === SyntaxKind.TypeLiteral;// && context.contextNode.parent.kind !== SyntaxKind.InterfaceDeclaration;
}
static IsTypeArgumentOrParameter(token: TextRangeWithKind, parent: Node): boolean {
static IsTypeArgumentOrParameterOrAssertion(token: TextRangeWithKind, parent: Node): boolean {
if (token.kind !== SyntaxKind.LessThanToken && token.kind !== SyntaxKind.GreaterThanToken) {
return false;
}
switch (parent.kind) {
case SyntaxKind.TypeReference:
case SyntaxKind.TypeAssertionExpression:
case SyntaxKind.ClassDeclaration:
case SyntaxKind.ClassExpression:
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.FunctionExpression:
@@ -721,6 +740,7 @@ namespace ts.formatting {
case SyntaxKind.ConstructSignature:
case SyntaxKind.CallExpression:
case SyntaxKind.NewExpression:
case SyntaxKind.ExpressionWithTypeArguments:
return true;
default:
return false;
@@ -728,9 +748,13 @@ namespace ts.formatting {
}
}
static IsTypeArgumentOrParameterContext(context: FormattingContext): boolean {
return Rules.IsTypeArgumentOrParameter(context.currentTokenSpan, context.currentTokenParent) ||
Rules.IsTypeArgumentOrParameter(context.nextTokenSpan, context.nextTokenParent);
static IsTypeArgumentOrParameterOrAssertionContext(context: FormattingContext): boolean {
return Rules.IsTypeArgumentOrParameterOrAssertion(context.currentTokenSpan, context.currentTokenParent) ||
Rules.IsTypeArgumentOrParameterOrAssertion(context.nextTokenSpan, context.nextTokenParent);
}
static IsTypeAssertionContext(context: FormattingContext): boolean {
return context.contextNode.kind === SyntaxKind.TypeAssertionExpression;
}
static IsVoidOpContext(context: FormattingContext): boolean {
+11
View File
@@ -71,6 +71,17 @@ namespace ts.formatting {
rules.push(this.globalRules.NoSpaceBetweenParens);
}
if ( options.InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets ) {
rules.push( this.globalRules.SpaceAfterOpenBracket );
rules.push( this.globalRules.SpaceBeforeCloseBracket );
rules.push( this.globalRules.NoSpaceBetweenBrackets );
}
else {
rules.push( this.globalRules.NoSpaceAfterOpenBracket );
rules.push( this.globalRules.NoSpaceBeforeCloseBracket );
rules.push( this.globalRules.NoSpaceBetweenBrackets );
}
if (options.InsertSpaceAfterSemicolonInForStatements) {
rules.push(this.globalRules.SpaceAfterSemicolonInFor);
}
+2
View File
@@ -418,6 +418,7 @@ namespace ts.formatting {
case SyntaxKind.DefaultClause:
case SyntaxKind.CaseClause:
case SyntaxKind.ParenthesizedExpression:
case SyntaxKind.PropertyAccessExpression:
case SyntaxKind.CallExpression:
case SyntaxKind.NewExpression:
case SyntaxKind.VariableStatement:
@@ -427,6 +428,7 @@ namespace ts.formatting {
case SyntaxKind.ConditionalExpression:
case SyntaxKind.ArrayBindingPattern:
case SyntaxKind.ObjectBindingPattern:
case SyntaxKind.JsxElement:
return true;
}
return false;
+303 -181
View File
File diff suppressed because it is too large Load Diff
+47 -8
View File
@@ -60,10 +60,12 @@ namespace ts {
getNewLine?(): string;
getProjectVersion?(): string;
useCaseSensitiveFileNames?(): boolean;
getModuleResolutionsForFile?(fileName: string): string;
}
/** Public interface of the the of a config service shim instance.*/
export interface CoreServicesShimHost extends Logger {
export interface CoreServicesShimHost extends Logger, ModuleResolutionHost {
/**
* Returns a JSON-encoded value of the type: string[]
*
@@ -205,6 +207,11 @@ namespace ts {
getFormattingEditsForDocument(fileName: string, options: string/*Services.FormatCodeOptions*/): string;
getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: string/*Services.FormatCodeOptions*/): string;
/**
* Returns JSON-encoded value of the type TextInsertion.
*/
getDocCommentTemplateAtPosition(fileName: string, position: number): string;
getEmitOutput(fileName: string): string;
}
@@ -265,8 +272,18 @@ namespace ts {
private files: string[];
private loggingEnabled = false;
private tracingEnabled = false;
public resolveModuleNames: (moduleName: string[], containingFile: string) => string[];
constructor(private shimHost: LanguageServiceShimHost) {
// if shimHost is a COM object then property check will become method call with no arguments.
// 'in' does not have this effect.
if ("getModuleResolutionsForFile" in this.shimHost) {
this.resolveModuleNames = (moduleNames: string[], containingFile: string) => {
let resolutionsInFile = <Map<string>>JSON.parse(this.shimHost.getModuleResolutionsForFile(containingFile));
return map(moduleNames, name => lookUp(resolutionsInFile, name));
};
}
}
public log(s: string): void {
@@ -405,6 +422,14 @@ namespace ts {
}
return JSON.parse(encoded);
}
public fileExists(fileName: string): boolean {
return this.shimHost.fileExists(fileName);
}
public readFile(fileName: string): string {
return this.shimHost.readFile(fileName);
}
}
function simpleForwardCall(logger: Logger, actionDescription: string, action: () => any, logPerformance: boolean): any {
@@ -529,7 +554,7 @@ namespace ts {
}
private realizeDiagnostics(diagnostics: Diagnostic[]): { message: string; start: number; length: number; category: string; }[]{
var newLine = this.getNewLine();
var newLine = getNewLineOrDefaultFromHost(this.host);
return ts.realizeDiagnostics(diagnostics, newLine);
}
@@ -571,10 +596,6 @@ namespace ts {
});
}
private getNewLine(): string {
return this.host.getNewLine ? this.host.getNewLine() : "\r\n";
}
public getSyntacticDiagnostics(fileName: string): string {
return this.forwardJSONCall(
"getSyntacticDiagnostics('" + fileName + "')",
@@ -751,7 +772,10 @@ namespace ts {
return this.forwardJSONCall(
"getDocumentHighlights('" + fileName + "', " + position + ")",
() => {
return this.languageService.getDocumentHighlights(fileName, position, JSON.parse(filesToSearch));
var results = this.languageService.getDocumentHighlights(fileName, position, JSON.parse(filesToSearch));
// workaround for VS document higlighting issue - keep only items from the initial file
let normalizedName = normalizeSlashes(fileName).toLowerCase();
return filter(results, r => normalizeSlashes(r.fileName).toLowerCase() === normalizedName);
});
}
@@ -811,6 +835,13 @@ namespace ts {
});
}
public getDocCommentTemplateAtPosition(fileName: string, position: number): string {
return this.forwardJSONCall(
"getDocCommentTemplateAtPosition('" + fileName + "', " + position + ")",
() => this.languageService.getDocCommentTemplateAtPosition(fileName, position)
);
}
/// NAVIGATE TO
/** Return a list of symbols that are interesting to navigate to */
@@ -907,6 +938,13 @@ namespace ts {
private forwardJSONCall(actionDescription: string, action: () => any): any {
return forwardJSONCall(this.logger, actionDescription, action, this.logPerformance);
}
public resolveModuleName(fileName: string, moduleName: string, compilerOptionsJson: string): string {
return this.forwardJSONCall(`resolveModuleName('${fileName}')`, () => {
let compilerOptions = <CompilerOptions>JSON.parse(compilerOptionsJson);
return resolveModuleName(moduleName, normalizeSlashes(fileName), compilerOptions, this.host);
});
}
public getPreProcessedFileInfo(fileName: string, sourceTextSnapshot: IScriptSnapshot): string {
return this.forwardJSONCall(
@@ -916,6 +954,7 @@ namespace ts {
var convertResult = {
referencedFiles: <IFileReference[]>[],
importedFiles: <IFileReference[]>[],
ambientExternalModules: result.ambientExternalModules,
isLibFile: result.isLibFile
};
+1 -3
View File
@@ -611,13 +611,11 @@ namespace ts.SignatureHelp {
let displayParts = mapToDisplayParts(writer =>
typeChecker.getSymbolDisplayBuilder().buildParameterDisplay(parameter, writer, invocation));
let isOptional = hasQuestionToken(parameter.valueDeclaration);
return {
name: parameter.name,
documentation: parameter.getDocumentationComment(),
displayParts,
isOptional
isOptional: typeChecker.isOptionalParameter(<ParameterDeclaration>parameter.valueDeclaration)
};
}
+62
View File
@@ -414,6 +414,60 @@ namespace ts {
}
}
}
export function isInString(sourceFile: SourceFile, position: number) {
let token = getTokenAtPosition(sourceFile, position);
return token && token.kind === SyntaxKind.StringLiteral && position > token.getStart();
}
export function isInComment(sourceFile: SourceFile, position: number) {
return isInCommentHelper(sourceFile, position, /*predicate*/ undefined);
}
/**
* Returns true if the cursor at position in sourceFile is within a comment that additionally
* satisfies predicate, and false otherwise.
*/
export function isInCommentHelper(sourceFile: SourceFile, position: number, predicate?: (c: CommentRange) => boolean): boolean {
let token = getTokenAtPosition(sourceFile, position);
if (token && position <= token.getStart()) {
let commentRanges = getLeadingCommentRanges(sourceFile.text, token.pos);
// The end marker of a single-line comment does not include the newline character.
// In the following case, we are inside a comment (^ denotes the cursor position):
//
// // asdf ^\n
//
// But for multi-line comments, we don't want to be inside the comment in the following case:
//
// /* asdf */^
//
// Internally, we represent the end of the comment at the newline and closing '/', respectively.
return predicate ?
forEach(commentRanges, c => c.pos < position &&
(c.kind == SyntaxKind.SingleLineCommentTrivia ? position <= c.end : position < c.end) &&
predicate(c)) :
forEach(commentRanges, c => c.pos < position &&
(c.kind == SyntaxKind.SingleLineCommentTrivia ? position <= c.end : position < c.end));
}
return false;
}
export function hasDocComment(sourceFile: SourceFile, position: number) {
let token = getTokenAtPosition(sourceFile, position);
// First, we have to see if this position actually landed in a comment.
let commentRanges = getLeadingCommentRanges(sourceFile.text, token.pos);
return forEach(commentRanges, jsDocPrefix);
function jsDocPrefix(c: CommentRange): boolean {
var text = sourceFile.text;
return text.length >= c.pos + 3 && text[c.pos] === '/' && text[c.pos + 1] === '*' && text[c.pos + 2] === '*';
}
}
function nodeHasTokens(n: Node): boolean {
// If we have a token or node that has a non-zero width, it must have tokens.
@@ -625,6 +679,14 @@ namespace ts {
return displayPart(text, SymbolDisplayPartKind.text);
}
const carriageReturnLineFeed = "\r\n";
/**
* The default is CRLF.
*/
export function getNewLineOrDefaultFromHost(host: LanguageServiceHost | LanguageServiceShimHost) {
return host.getNewLine ? host.getNewLine() : carriageReturnLineFeed;
}
export function lineBreakPart() {
return displayPart("\n", SymbolDisplayPartKind.lineBreak);
}
+12 -12
View File
@@ -75,28 +75,28 @@ function delint(sourceFile) {
delintNode(sourceFile);
function delintNode(node) {
switch (node.kind) {
case 196 /* ForStatement */:
case 197 /* ForInStatement */:
case 195 /* WhileStatement */:
case 194 /* DoStatement */:
if (node.statement.kind !== 189 /* Block */) {
case 197 /* ForStatement */:
case 198 /* ForInStatement */:
case 196 /* WhileStatement */:
case 195 /* DoStatement */:
if (node.statement.kind !== 190 /* Block */) {
report(node, "A looping statement's contents should be wrapped in a block body.");
}
break;
case 193 /* IfStatement */:
case 194 /* IfStatement */:
var ifStatement = node;
if (ifStatement.thenStatement.kind !== 189 /* Block */) {
if (ifStatement.thenStatement.kind !== 190 /* Block */) {
report(ifStatement.thenStatement, "An if statement's contents should be wrapped in a block body.");
}
if (ifStatement.elseStatement &&
ifStatement.elseStatement.kind !== 189 /* Block */ &&
ifStatement.elseStatement.kind !== 193 /* IfStatement */) {
ifStatement.elseStatement.kind !== 190 /* Block */ &&
ifStatement.elseStatement.kind !== 194 /* IfStatement */) {
report(ifStatement.elseStatement, "An else statement's contents should be wrapped in a block body.");
}
break;
case 178 /* BinaryExpression */:
case 179 /* BinaryExpression */:
var op = node.operatorToken.kind;
if (op === 29 /* EqualsEqualsToken */ || op == 30 /* ExclamationEqualsToken */) {
if (op === 30 /* EqualsEqualsToken */ || op == 31 /* ExclamationEqualsToken */) {
report(node, "Use '===' and '!=='.");
}
break;
@@ -112,7 +112,7 @@ exports.delint = delint;
var fileNames = process.argv.slice(2);
fileNames.forEach(function (fileName) {
// Parse a file
var sourceFile = ts.createSourceFile(fileName, readFileSync(fileName).toString(), 2 /* ES6 */, true);
var sourceFile = ts.createSourceFile(fileName, readFileSync(fileName).toString(), 2 /* ES6 */, /*setParentNodes */ true);
// delint it
delint(sourceFile);
});
@@ -22,8 +22,8 @@ System.register(['foo'], function(exports_1) {
var cls, cls2, x, y, z, M;
return {
setters:[
function (_alias) {
alias = _alias;
function (alias_1) {
alias = alias_1;
}],
execute: function() {
cls = alias.Class;
@@ -21,8 +21,8 @@ System.register(["foo"], function(exports_1) {
var cls, cls2, x, y, z, M;
return {
setters:[
function (_foo_1) {
foo_1 = _foo_1;
function (foo_1_1) {
foo_1 = foo_1_1;
}],
execute: function() {
cls = foo_1.alias.Class;
@@ -1,6 +1,7 @@
tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSupertype.ts(9,7): error TS2415: Class 'Derived<U>' incorrectly extends base class 'Base'.
Types of property 'x' are incompatible.
Type 'U' is not assignable to type 'string'.
Type 'String' is not assignable to type 'string'.
==== tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSupertype.ts (1 errors) ====
@@ -17,5 +18,6 @@ tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSuperty
!!! error TS2415: Class 'Derived<U>' incorrectly extends base class 'Base'.
!!! error TS2415: Types of property 'x' are incompatible.
!!! error TS2415: Type 'U' is not assignable to type 'string'.
!!! error TS2415: Type 'String' is not assignable to type 'string'.
x: U;
}
@@ -72,14 +72,14 @@ var temp2: [number[], string[]] = [[1, 2, 3], ["hello", "string"]];
interface myArray extends Array<Number> { }
>myArray : Symbol(myArray, Decl(arrayLiterals2ES6.ts, 40, 67))
>Array : Symbol(Array, Decl(lib.d.ts, 1000, 23), Decl(lib.d.ts, 1171, 11), Decl(lib.d.ts, 1452, 1))
>Array : Symbol(Array, Decl(lib.d.ts, 1000, 23), Decl(lib.d.ts, 1171, 11), Decl(lib.d.ts, 1455, 1))
>Number : Symbol(Number, Decl(lib.d.ts, 456, 40), Decl(lib.d.ts, 518, 11))
interface myArray2 extends Array<Number|String> { }
>myArray2 : Symbol(myArray2, Decl(arrayLiterals2ES6.ts, 42, 43))
>Array : Symbol(Array, Decl(lib.d.ts, 1000, 23), Decl(lib.d.ts, 1171, 11), Decl(lib.d.ts, 1452, 1))
>Array : Symbol(Array, Decl(lib.d.ts, 1000, 23), Decl(lib.d.ts, 1171, 11), Decl(lib.d.ts, 1455, 1))
>Number : Symbol(Number, Decl(lib.d.ts, 456, 40), Decl(lib.d.ts, 518, 11))
>String : Symbol(String, Decl(lib.d.ts, 275, 1), Decl(lib.d.ts, 443, 11), Decl(lib.d.ts, 1556, 1))
>String : Symbol(String, Decl(lib.d.ts, 275, 1), Decl(lib.d.ts, 443, 11), Decl(lib.d.ts, 1573, 1))
var d0 = [1, true, ...temp, ]; // has type (string|number|boolean)[]
>d0 : Symbol(d0, Decl(arrayLiterals2ES6.ts, 44, 3))
@@ -1,18 +1,21 @@
tests/cases/compiler/assignmentCompat1.ts(4,1): error TS2322: Type '{ [index: string]: any; }' is not assignable to type '{ one: number; }'.
Property 'one' is missing in type '{ [index: string]: any; }'.
tests/cases/compiler/assignmentCompat1.ts(5,1): error TS2322: Type '{ one: number; }' is not assignable to type '{ [index: string]: any; }'.
Index signature is missing in type '{ one: number; }'.
tests/cases/compiler/assignmentCompat1.ts(6,1): error TS2322: Type '{ [index: number]: any; }' is not assignable to type '{ one: number; }'.
Property 'one' is missing in type '{ [index: number]: any; }'.
==== tests/cases/compiler/assignmentCompat1.ts (2 errors) ====
var x = {one: 1};
var y: {[index:string]: any};
x = y;
var x = { one: 1 };
var y: { [index: string]: any };
var z: { [index: number]: any };
x = y; // Error
~
!!! error TS2322: Type '{ [index: string]: any; }' is not assignable to type '{ one: number; }'.
!!! error TS2322: Property 'one' is missing in type '{ [index: string]: any; }'.
y = x;
y = x; // Ok because index signature type is any
x = z; // Error
~
!!! error TS2322: Type '{ one: number; }' is not assignable to type '{ [index: string]: any; }'.
!!! error TS2322: Index signature is missing in type '{ one: number; }'.
!!! error TS2322: Type '{ [index: number]: any; }' is not assignable to type '{ one: number; }'.
!!! error TS2322: Property 'one' is missing in type '{ [index: number]: any; }'.
z = x; // Ok because index signature type is any
+13 -7
View File
@@ -1,12 +1,18 @@
//// [assignmentCompat1.ts]
var x = {one: 1};
var y: {[index:string]: any};
x = y;
y = x;
var x = { one: 1 };
var y: { [index: string]: any };
var z: { [index: number]: any };
x = y; // Error
y = x; // Ok because index signature type is any
x = z; // Error
z = x; // Ok because index signature type is any
//// [assignmentCompat1.js]
var x = { one: 1 };
var y;
x = y;
y = x;
var z;
x = y; // Error
y = x; // Ok because index signature type is any
x = z; // Error
z = x; // Ok because index signature type is any
@@ -12,12 +12,14 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer.ts(33,9): error TS2322: Type 'A<T>' is not assignable to type '{ [x: number]: Derived; }'.
Index signatures are incompatible.
Type 'T' is not assignable to type 'Derived'.
Type 'Base' is not assignable to type 'Derived'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer.ts(36,9): error TS2322: Type '{ [x: number]: Derived2; }' is not assignable to type 'A<T>'.
Index signatures are incompatible.
Type 'Derived2' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer.ts(37,9): error TS2322: Type 'A<T>' is not assignable to type '{ [x: number]: Derived2; }'.
Index signatures are incompatible.
Type 'T' is not assignable to type 'Derived2'.
Type 'Base' is not assignable to type 'Derived2'.
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer.ts (6 errors) ====
@@ -72,6 +74,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
!!! error TS2322: Type 'A<T>' is not assignable to type '{ [x: number]: Derived; }'.
!!! error TS2322: Index signatures are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'Derived'.
!!! error TS2322: Type 'Base' is not assignable to type 'Derived'.
var b2: { [x: number]: Derived2; }
a = b2; // error
@@ -84,6 +87,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
!!! error TS2322: Type 'A<T>' is not assignable to type '{ [x: number]: Derived2; }'.
!!! error TS2322: Index signatures are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'Derived2'.
!!! error TS2322: Type 'Base' is not assignable to type 'Derived2'.
var b3: { [x: number]: T; }
a = b3; // ok
@@ -12,12 +12,14 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer2.ts(33,9): error TS2322: Type 'A<T>' is not assignable to type '{ [x: number]: Derived; }'.
Index signatures are incompatible.
Type 'T' is not assignable to type 'Derived'.
Type 'Base' is not assignable to type 'Derived'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer2.ts(36,9): error TS2322: Type '{ [x: number]: Derived2; }' is not assignable to type 'A<T>'.
Index signatures are incompatible.
Type 'Derived2' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer2.ts(37,9): error TS2322: Type 'A<T>' is not assignable to type '{ [x: number]: Derived2; }'.
Index signatures are incompatible.
Type 'T' is not assignable to type 'Derived2'.
Type 'Base' is not assignable to type 'Derived2'.
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer2.ts (6 errors) ====
@@ -72,6 +74,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
!!! error TS2322: Type 'A<T>' is not assignable to type '{ [x: number]: Derived; }'.
!!! error TS2322: Index signatures are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'Derived'.
!!! error TS2322: Type 'Base' is not assignable to type 'Derived'.
var b2: { [x: number]: Derived2; }
a = b2; // error
@@ -84,6 +87,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
!!! error TS2322: Type 'A<T>' is not assignable to type '{ [x: number]: Derived2; }'.
!!! error TS2322: Index signatures are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'Derived2'.
!!! error TS2322: Type 'Base' is not assignable to type 'Derived2'.
var b3: { [x: number]: T; }
a = b3; // ok
@@ -18,12 +18,14 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer.ts(47,9): error TS2322: Type 'A<T>' is not assignable to type '{ [x: string]: Derived; }'.
Index signatures are incompatible.
Type 'T' is not assignable to type 'Derived'.
Type 'Base' is not assignable to type 'Derived'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer.ts(50,9): error TS2322: Type '{ [x: string]: Derived2; }' is not assignable to type 'A<T>'.
Index signatures are incompatible.
Type 'Derived2' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer.ts(51,9): error TS2322: Type 'A<T>' is not assignable to type '{ [x: string]: Derived2; }'.
Index signatures are incompatible.
Type 'T' is not assignable to type 'Derived2'.
Type 'Base' is not assignable to type 'Derived2'.
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer.ts (8 errors) ====
@@ -100,6 +102,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
!!! error TS2322: Type 'A<T>' is not assignable to type '{ [x: string]: Derived; }'.
!!! error TS2322: Index signatures are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'Derived'.
!!! error TS2322: Type 'Base' is not assignable to type 'Derived'.
var b4: { [x: string]: Derived2; };
a3 = b4; // error
@@ -112,5 +115,6 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
!!! error TS2322: Type 'A<T>' is not assignable to type '{ [x: string]: Derived2; }'.
!!! error TS2322: Index signatures are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'Derived2'.
!!! error TS2322: Type 'Base' is not assignable to type 'Derived2'.
}
}
@@ -18,12 +18,14 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer2.ts(47,9): error TS2322: Type 'A<T>' is not assignable to type '{ [x: string]: Derived; }'.
Index signatures are incompatible.
Type 'T' is not assignable to type 'Derived'.
Type 'Base' is not assignable to type 'Derived'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer2.ts(50,9): error TS2322: Type '{ [x: string]: Derived2; }' is not assignable to type 'A<T>'.
Index signatures are incompatible.
Type 'Derived2' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer2.ts(51,9): error TS2322: Type 'A<T>' is not assignable to type '{ [x: string]: Derived2; }'.
Index signatures are incompatible.
Type 'T' is not assignable to type 'Derived2'.
Type 'Base' is not assignable to type 'Derived2'.
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer2.ts (8 errors) ====
@@ -100,6 +102,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
!!! error TS2322: Type 'A<T>' is not assignable to type '{ [x: string]: Derived; }'.
!!! error TS2322: Index signatures are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'Derived'.
!!! error TS2322: Type 'Base' is not assignable to type 'Derived'.
var b4: { [x: string]: Derived2; };
a3 = b4; // error
@@ -112,5 +115,6 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
!!! error TS2322: Type 'A<T>' is not assignable to type '{ [x: string]: Derived2; }'.
!!! error TS2322: Index signatures are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'Derived2'.
!!! error TS2322: Type 'Base' is not assignable to type 'Derived2'.
}
}
@@ -5,6 +5,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer3.ts(21,9): error TS2322: Type 'A<T>' is not assignable to type '{ [x: string]: string; }'.
Index signatures are incompatible.
Type 'T' is not assignable to type 'string'.
Type 'Derived' is not assignable to type 'string'.
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer3.ts (3 errors) ====
@@ -39,5 +40,6 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
!!! error TS2322: Type 'A<T>' is not assignable to type '{ [x: string]: string; }'.
!!! error TS2322: Index signatures are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'string'.
!!! error TS2322: Type 'Derived' is not assignable to type 'string'.
}
}
@@ -1,17 +0,0 @@
tests/cases/compiler/assignmentCompatability36.ts(9,1): error TS2322: Type 'interfaceWithPublicAndOptional<number, string>' is not assignable to type '{ [index: string]: any; }'.
Index signature is missing in type 'interfaceWithPublicAndOptional<number, string>'.
==== tests/cases/compiler/assignmentCompatability36.ts (1 errors) ====
module __test1__ {
export interface interfaceWithPublicAndOptional<T,U> { one: T; two?: U; }; var obj4: interfaceWithPublicAndOptional<number,string> = { one: 1 };;
export var __val__obj4 = obj4;
}
module __test2__ {
export var aa:{[index:string]:any;};;
export var __val__aa = aa;
}
__test2__.__val__aa = __test1__.__val__obj4
~~~~~~~~~~~~~~~~~~~
!!! error TS2322: Type 'interfaceWithPublicAndOptional<number, string>' is not assignable to type '{ [index: string]: any; }'.
!!! error TS2322: Index signature is missing in type 'interfaceWithPublicAndOptional<number, string>'.
@@ -0,0 +1,39 @@
=== tests/cases/compiler/assignmentCompatability36.ts ===
module __test1__ {
>__test1__ : Symbol(__test1__, Decl(assignmentCompatability36.ts, 0, 0))
export interface interfaceWithPublicAndOptional<T,U> { one: T; two?: U; }; var obj4: interfaceWithPublicAndOptional<number,string> = { one: 1 };;
>interfaceWithPublicAndOptional : Symbol(interfaceWithPublicAndOptional, Decl(assignmentCompatability36.ts, 0, 18))
>T : Symbol(T, Decl(assignmentCompatability36.ts, 1, 52))
>U : Symbol(U, Decl(assignmentCompatability36.ts, 1, 54))
>one : Symbol(one, Decl(assignmentCompatability36.ts, 1, 58))
>T : Symbol(T, Decl(assignmentCompatability36.ts, 1, 52))
>two : Symbol(two, Decl(assignmentCompatability36.ts, 1, 66))
>U : Symbol(U, Decl(assignmentCompatability36.ts, 1, 54))
>obj4 : Symbol(obj4, Decl(assignmentCompatability36.ts, 1, 83))
>interfaceWithPublicAndOptional : Symbol(interfaceWithPublicAndOptional, Decl(assignmentCompatability36.ts, 0, 18))
>one : Symbol(one, Decl(assignmentCompatability36.ts, 1, 139))
export var __val__obj4 = obj4;
>__val__obj4 : Symbol(__val__obj4, Decl(assignmentCompatability36.ts, 2, 14))
>obj4 : Symbol(obj4, Decl(assignmentCompatability36.ts, 1, 83))
}
module __test2__ {
>__test2__ : Symbol(__test2__, Decl(assignmentCompatability36.ts, 3, 1))
export var aa:{[index:string]:any;};;
>aa : Symbol(aa, Decl(assignmentCompatability36.ts, 5, 14))
>index : Symbol(index, Decl(assignmentCompatability36.ts, 5, 20))
export var __val__aa = aa;
>__val__aa : Symbol(__val__aa, Decl(assignmentCompatability36.ts, 6, 14))
>aa : Symbol(aa, Decl(assignmentCompatability36.ts, 5, 14))
}
__test2__.__val__aa = __test1__.__val__obj4
>__test2__.__val__aa : Symbol(__test2__.__val__aa, Decl(assignmentCompatability36.ts, 6, 14))
>__test2__ : Symbol(__test2__, Decl(assignmentCompatability36.ts, 3, 1))
>__val__aa : Symbol(__test2__.__val__aa, Decl(assignmentCompatability36.ts, 6, 14))
>__test1__.__val__obj4 : Symbol(__test1__.__val__obj4, Decl(assignmentCompatability36.ts, 2, 14))
>__test1__ : Symbol(__test1__, Decl(assignmentCompatability36.ts, 0, 0))
>__val__obj4 : Symbol(__test1__.__val__obj4, Decl(assignmentCompatability36.ts, 2, 14))
@@ -0,0 +1,42 @@
=== tests/cases/compiler/assignmentCompatability36.ts ===
module __test1__ {
>__test1__ : typeof __test1__
export interface interfaceWithPublicAndOptional<T,U> { one: T; two?: U; }; var obj4: interfaceWithPublicAndOptional<number,string> = { one: 1 };;
>interfaceWithPublicAndOptional : interfaceWithPublicAndOptional<T, U>
>T : T
>U : U
>one : T
>T : T
>two : U
>U : U
>obj4 : interfaceWithPublicAndOptional<number, string>
>interfaceWithPublicAndOptional : interfaceWithPublicAndOptional<T, U>
>{ one: 1 } : { one: number; }
>one : number
>1 : number
export var __val__obj4 = obj4;
>__val__obj4 : interfaceWithPublicAndOptional<number, string>
>obj4 : interfaceWithPublicAndOptional<number, string>
}
module __test2__ {
>__test2__ : typeof __test2__
export var aa:{[index:string]:any;};;
>aa : { [index: string]: any; }
>index : string
export var __val__aa = aa;
>__val__aa : { [index: string]: any; }
>aa : { [index: string]: any; }
}
__test2__.__val__aa = __test1__.__val__obj4
>__test2__.__val__aa = __test1__.__val__obj4 : __test1__.interfaceWithPublicAndOptional<number, string>
>__test2__.__val__aa : { [index: string]: any; }
>__test2__ : typeof __test2__
>__val__aa : { [index: string]: any; }
>__test1__.__val__obj4 : __test1__.interfaceWithPublicAndOptional<number, string>
>__test1__ : typeof __test1__
>__val__obj4 : __test1__.interfaceWithPublicAndOptional<number, string>
@@ -0,0 +1,42 @@
//// [assignmentNonObjectTypeConstraints.ts]
const enum E { A, B, C }
function foo<T extends number>(x: T) {
var y: number = x; // Ok
}
foo(5);
foo(E.A);
class A { a }
class B { b }
function bar<T extends A | B>(x: T) {
var y: A | B = x; // Ok
}
bar(new A);
bar(new B);
//// [assignmentNonObjectTypeConstraints.js]
function foo(x) {
var y = x; // Ok
}
foo(5);
foo(0 /* A */);
var A = (function () {
function A() {
}
return A;
})();
var B = (function () {
function B() {
}
return B;
})();
function bar(x) {
var y = x; // Ok
}
bar(new A);
bar(new B);
@@ -0,0 +1,58 @@
=== tests/cases/compiler/assignmentNonObjectTypeConstraints.ts ===
const enum E { A, B, C }
>E : Symbol(E, Decl(assignmentNonObjectTypeConstraints.ts, 0, 0))
>A : Symbol(E.A, Decl(assignmentNonObjectTypeConstraints.ts, 0, 14))
>B : Symbol(E.B, Decl(assignmentNonObjectTypeConstraints.ts, 0, 17))
>C : Symbol(E.C, Decl(assignmentNonObjectTypeConstraints.ts, 0, 20))
function foo<T extends number>(x: T) {
>foo : Symbol(foo, Decl(assignmentNonObjectTypeConstraints.ts, 0, 24))
>T : Symbol(T, Decl(assignmentNonObjectTypeConstraints.ts, 2, 13))
>x : Symbol(x, Decl(assignmentNonObjectTypeConstraints.ts, 2, 31))
>T : Symbol(T, Decl(assignmentNonObjectTypeConstraints.ts, 2, 13))
var y: number = x; // Ok
>y : Symbol(y, Decl(assignmentNonObjectTypeConstraints.ts, 3, 7))
>x : Symbol(x, Decl(assignmentNonObjectTypeConstraints.ts, 2, 31))
}
foo(5);
>foo : Symbol(foo, Decl(assignmentNonObjectTypeConstraints.ts, 0, 24))
foo(E.A);
>foo : Symbol(foo, Decl(assignmentNonObjectTypeConstraints.ts, 0, 24))
>E.A : Symbol(E.A, Decl(assignmentNonObjectTypeConstraints.ts, 0, 14))
>E : Symbol(E, Decl(assignmentNonObjectTypeConstraints.ts, 0, 0))
>A : Symbol(E.A, Decl(assignmentNonObjectTypeConstraints.ts, 0, 14))
class A { a }
>A : Symbol(A, Decl(assignmentNonObjectTypeConstraints.ts, 7, 9))
>a : Symbol(a, Decl(assignmentNonObjectTypeConstraints.ts, 9, 9))
class B { b }
>B : Symbol(B, Decl(assignmentNonObjectTypeConstraints.ts, 9, 13))
>b : Symbol(b, Decl(assignmentNonObjectTypeConstraints.ts, 10, 9))
function bar<T extends A | B>(x: T) {
>bar : Symbol(bar, Decl(assignmentNonObjectTypeConstraints.ts, 10, 13))
>T : Symbol(T, Decl(assignmentNonObjectTypeConstraints.ts, 12, 13))
>A : Symbol(A, Decl(assignmentNonObjectTypeConstraints.ts, 7, 9))
>B : Symbol(B, Decl(assignmentNonObjectTypeConstraints.ts, 9, 13))
>x : Symbol(x, Decl(assignmentNonObjectTypeConstraints.ts, 12, 30))
>T : Symbol(T, Decl(assignmentNonObjectTypeConstraints.ts, 12, 13))
var y: A | B = x; // Ok
>y : Symbol(y, Decl(assignmentNonObjectTypeConstraints.ts, 13, 7))
>A : Symbol(A, Decl(assignmentNonObjectTypeConstraints.ts, 7, 9))
>B : Symbol(B, Decl(assignmentNonObjectTypeConstraints.ts, 9, 13))
>x : Symbol(x, Decl(assignmentNonObjectTypeConstraints.ts, 12, 30))
}
bar(new A);
>bar : Symbol(bar, Decl(assignmentNonObjectTypeConstraints.ts, 10, 13))
>A : Symbol(A, Decl(assignmentNonObjectTypeConstraints.ts, 7, 9))
bar(new B);
>bar : Symbol(bar, Decl(assignmentNonObjectTypeConstraints.ts, 10, 13))
>B : Symbol(B, Decl(assignmentNonObjectTypeConstraints.ts, 9, 13))
@@ -0,0 +1,65 @@
=== tests/cases/compiler/assignmentNonObjectTypeConstraints.ts ===
const enum E { A, B, C }
>E : E
>A : E
>B : E
>C : E
function foo<T extends number>(x: T) {
>foo : <T extends number>(x: T) => void
>T : T
>x : T
>T : T
var y: number = x; // Ok
>y : number
>x : T
}
foo(5);
>foo(5) : void
>foo : <T extends number>(x: T) => void
>5 : number
foo(E.A);
>foo(E.A) : void
>foo : <T extends number>(x: T) => void
>E.A : E
>E : typeof E
>A : E
class A { a }
>A : A
>a : any
class B { b }
>B : B
>b : any
function bar<T extends A | B>(x: T) {
>bar : <T extends A | B>(x: T) => void
>T : T
>A : A
>B : B
>x : T
>T : T
var y: A | B = x; // Ok
>y : A | B
>A : A
>B : B
>x : T
}
bar(new A);
>bar(new A) : void
>bar : <T extends A | B>(x: T) => void
>new A : A
>A : typeof A
bar(new B);
>bar(new B) : void
>bar : <T extends A | B>(x: T) => void
>new B : B
>B : typeof B
@@ -2,6 +2,6 @@
var foo = async (): Promise<void> => {
>foo : Symbol(foo, Decl(asyncArrowFunction1_es6.ts, 1, 3))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
};
@@ -2,16 +2,16 @@
type MyPromise<T> = Promise<T>;
>MyPromise : Symbol(MyPromise, Decl(asyncAwait_es6.ts, 0, 0), Decl(asyncAwait_es6.ts, 1, 11))
>T : Symbol(T, Decl(asyncAwait_es6.ts, 0, 15))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
>T : Symbol(T, Decl(asyncAwait_es6.ts, 0, 15))
declare var MyPromise: typeof Promise;
>MyPromise : Symbol(MyPromise, Decl(asyncAwait_es6.ts, 0, 0), Decl(asyncAwait_es6.ts, 1, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
declare var p: Promise<number>;
>p : Symbol(p, Decl(asyncAwait_es6.ts, 2, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
declare var mp: MyPromise<number>;
>mp : Symbol(mp, Decl(asyncAwait_es6.ts, 3, 11))
@@ -22,7 +22,7 @@ async function f0() { }
async function f1(): Promise<void> { }
>f1 : Symbol(f1, Decl(asyncAwait_es6.ts, 5, 23))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
async function f3(): MyPromise<void> { }
>f3 : Symbol(f3, Decl(asyncAwait_es6.ts, 6, 38))
@@ -33,7 +33,7 @@ let f4 = async function() { }
let f5 = async function(): Promise<void> { }
>f5 : Symbol(f5, Decl(asyncAwait_es6.ts, 10, 3))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
let f6 = async function(): MyPromise<void> { }
>f6 : Symbol(f6, Decl(asyncAwait_es6.ts, 11, 3))
@@ -44,7 +44,7 @@ let f7 = async () => { };
let f8 = async (): Promise<void> => { };
>f8 : Symbol(f8, Decl(asyncAwait_es6.ts, 14, 3))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
let f9 = async (): MyPromise<void> => { };
>f9 : Symbol(f9, Decl(asyncAwait_es6.ts, 15, 3))
@@ -60,7 +60,7 @@ let f11 = async () => mp;
let f12 = async (): Promise<number> => mp;
>f12 : Symbol(f12, Decl(asyncAwait_es6.ts, 18, 3))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
>mp : Symbol(mp, Decl(asyncAwait_es6.ts, 3, 11))
let f13 = async (): MyPromise<number> => p;
@@ -76,7 +76,7 @@ let o = {
async m2(): Promise<void> { },
>m2 : Symbol(m2, Decl(asyncAwait_es6.ts, 22, 16))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
async m3(): MyPromise<void> { }
>m3 : Symbol(m3, Decl(asyncAwait_es6.ts, 23, 31))
@@ -92,7 +92,7 @@ class C {
async m2(): Promise<void> { }
>m2 : Symbol(m2, Decl(asyncAwait_es6.ts, 28, 15))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
async m3(): MyPromise<void> { }
>m3 : Symbol(m3, Decl(asyncAwait_es6.ts, 29, 30))
@@ -103,7 +103,7 @@ class C {
static async m5(): Promise<void> { }
>m5 : Symbol(C.m5, Decl(asyncAwait_es6.ts, 31, 22))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
static async m6(): MyPromise<void> { }
>m6 : Symbol(C.m6, Decl(asyncAwait_es6.ts, 32, 37))
@@ -1,5 +1,5 @@
=== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration11_es6.ts ===
async function await(): Promise<void> {
>await : Symbol(await, Decl(asyncFunctionDeclaration11_es6.ts, 0, 0))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
}
@@ -1,7 +1,7 @@
=== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration14_es6.ts ===
async function foo(): Promise<void> {
>foo : Symbol(foo, Decl(asyncFunctionDeclaration14_es6.ts, 0, 0))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
return;
}
@@ -1,5 +1,5 @@
=== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration1_es6.ts ===
async function foo(): Promise<void> {
>foo : Symbol(foo, Decl(asyncFunctionDeclaration1_es6.ts, 0, 0))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
}
@@ -4,11 +4,11 @@ declare var a: boolean;
declare var p: Promise<boolean>;
>p : Symbol(p, Decl(awaitBinaryExpression1_es6.ts, 1, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
async function func(): Promise<void> {
>func : Symbol(func, Decl(awaitBinaryExpression1_es6.ts, 1, 32))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
"before";
var b = await p || a;
@@ -4,11 +4,11 @@ declare var a: boolean;
declare var p: Promise<boolean>;
>p : Symbol(p, Decl(awaitBinaryExpression2_es6.ts, 1, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
async function func(): Promise<void> {
>func : Symbol(func, Decl(awaitBinaryExpression2_es6.ts, 1, 32))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
"before";
var b = await p && a;
@@ -4,11 +4,11 @@ declare var a: number;
declare var p: Promise<number>;
>p : Symbol(p, Decl(awaitBinaryExpression3_es6.ts, 1, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
async function func(): Promise<void> {
>func : Symbol(func, Decl(awaitBinaryExpression3_es6.ts, 1, 31))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
"before";
var b = await p + a;
@@ -4,11 +4,11 @@ declare var a: boolean;
declare var p: Promise<boolean>;
>p : Symbol(p, Decl(awaitBinaryExpression4_es6.ts, 1, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
async function func(): Promise<void> {
>func : Symbol(func, Decl(awaitBinaryExpression4_es6.ts, 1, 32))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
"before";
var b = await p, a;
@@ -4,11 +4,11 @@ declare var a: boolean;
declare var p: Promise<boolean>;
>p : Symbol(p, Decl(awaitBinaryExpression5_es6.ts, 1, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
async function func(): Promise<void> {
>func : Symbol(func, Decl(awaitBinaryExpression5_es6.ts, 1, 32))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
"before";
var o: { a: boolean; };
@@ -4,7 +4,7 @@ declare var a: boolean;
declare var p: Promise<boolean>;
>p : Symbol(p, Decl(awaitCallExpression1_es6.ts, 1, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void;
>fn : Symbol(fn, Decl(awaitCallExpression1_es6.ts, 1, 32))
@@ -21,14 +21,14 @@ declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; };
declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>;
>pfn : Symbol(pfn, Decl(awaitCallExpression1_es6.ts, 4, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
>arg0 : Symbol(arg0, Decl(awaitCallExpression1_es6.ts, 4, 28))
>arg1 : Symbol(arg1, Decl(awaitCallExpression1_es6.ts, 4, 42))
>arg2 : Symbol(arg2, Decl(awaitCallExpression1_es6.ts, 4, 57))
declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>;
>po : Symbol(po, Decl(awaitCallExpression1_es6.ts, 5, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
>fn : Symbol(fn, Decl(awaitCallExpression1_es6.ts, 5, 25))
>arg0 : Symbol(arg0, Decl(awaitCallExpression1_es6.ts, 5, 29))
>arg1 : Symbol(arg1, Decl(awaitCallExpression1_es6.ts, 5, 43))
@@ -36,7 +36,7 @@ declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void;
async function func(): Promise<void> {
>func : Symbol(func, Decl(awaitCallExpression1_es6.ts, 5, 84))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
"before";
var b = fn(a, a, a);
@@ -4,7 +4,7 @@ declare var a: boolean;
declare var p: Promise<boolean>;
>p : Symbol(p, Decl(awaitCallExpression2_es6.ts, 1, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void;
>fn : Symbol(fn, Decl(awaitCallExpression2_es6.ts, 1, 32))
@@ -21,14 +21,14 @@ declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; };
declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>;
>pfn : Symbol(pfn, Decl(awaitCallExpression2_es6.ts, 4, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
>arg0 : Symbol(arg0, Decl(awaitCallExpression2_es6.ts, 4, 28))
>arg1 : Symbol(arg1, Decl(awaitCallExpression2_es6.ts, 4, 42))
>arg2 : Symbol(arg2, Decl(awaitCallExpression2_es6.ts, 4, 57))
declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>;
>po : Symbol(po, Decl(awaitCallExpression2_es6.ts, 5, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
>fn : Symbol(fn, Decl(awaitCallExpression2_es6.ts, 5, 25))
>arg0 : Symbol(arg0, Decl(awaitCallExpression2_es6.ts, 5, 29))
>arg1 : Symbol(arg1, Decl(awaitCallExpression2_es6.ts, 5, 43))
@@ -36,7 +36,7 @@ declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void;
async function func(): Promise<void> {
>func : Symbol(func, Decl(awaitCallExpression2_es6.ts, 5, 84))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
"before";
var b = fn(await p, a, a);
@@ -4,7 +4,7 @@ declare var a: boolean;
declare var p: Promise<boolean>;
>p : Symbol(p, Decl(awaitCallExpression3_es6.ts, 1, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
declare function fn(arg0: boolean, arg1: boolean, arg2: boolean): void;
>fn : Symbol(fn, Decl(awaitCallExpression3_es6.ts, 1, 32))
@@ -21,14 +21,14 @@ declare var o: { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; };
declare var pfn: Promise<{ (arg0: boolean, arg1: boolean, arg2: boolean): void; }>;
>pfn : Symbol(pfn, Decl(awaitCallExpression3_es6.ts, 4, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
>arg0 : Symbol(arg0, Decl(awaitCallExpression3_es6.ts, 4, 28))
>arg1 : Symbol(arg1, Decl(awaitCallExpression3_es6.ts, 4, 42))
>arg2 : Symbol(arg2, Decl(awaitCallExpression3_es6.ts, 4, 57))
declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>;
>po : Symbol(po, Decl(awaitCallExpression3_es6.ts, 5, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
>fn : Symbol(fn, Decl(awaitCallExpression3_es6.ts, 5, 25))
>arg0 : Symbol(arg0, Decl(awaitCallExpression3_es6.ts, 5, 29))
>arg1 : Symbol(arg1, Decl(awaitCallExpression3_es6.ts, 5, 43))
@@ -36,7 +36,7 @@ declare var po: Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void;
async function func(): Promise<void> {
>func : Symbol(func, Decl(awaitCallExpression3_es6.ts, 5, 84))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4832, 1), Decl(lib.d.ts, 4918, 11))
"before";
var b = fn(a, await p, a);

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