Merge branch 'master' into tscJsFiles

This commit is contained in:
Sheetal Nandi
2015-10-05 16:42:37 -07:00
527 changed files with 9938 additions and 4557 deletions
+3 -2
View File
@@ -40,5 +40,6 @@ scripts/typings/
coverage/
internal/
**/.DS_Store
.settings/*
!.settings/tasks.json
.settings
.vscode/*
!.vscode/tasks.json
+7 -2
View File
@@ -3,6 +3,11 @@ doc
scripts
src
tests
Jakefile
internal
tslint.json
Jakefile.js
.editorconfig
.gitattributes
.settings/
.travis.yml
.settings/
.vscode/
+19
View File
@@ -18,6 +18,25 @@
"problemMatcher": [
"$tsc"
]
},
{
"taskName": "lint-server",
"args": [],
"problemMatcher": {
"owner": "typescript",
"fileLocation": ["relative", "${workspaceRoot}"],
"pattern": {
"regexp": "^(warning|error)\\s+([^(]+)\\s+\\((\\d+|\\d+,\\d+|\\d+,\\d+,\\d+,\\d+)\\):\\s+(.*)$",
"severity": 1,
"file": 2,
"location": 3,
"message": 4
},
"watchedTaskBeginsRegExp": "^\\*\\*\\*Lint failure\\*\\*\\*$",
"watchedTaskEndsRegExp": "^\\*\\*\\* Total \\d+ failures\\.$"
},
"showOutput": "always",
"isWatching": true
}
]
}
+1 -1
View File
@@ -9,7 +9,7 @@ Design changes will not be accepted at this time. If you have a design change pr
## Legal
You will need to complete a Contributor License Agreement (CLA). Briefly, this agreement testifies that you are granting us permission to use the submitted change according to the terms of the project's license, and that the work being submitted is under appropriate copyright.
Please submit a Contributor License Agreement (CLA) before submitting a pull request. You may visit https://cla.microsoft.com to sign digitally. Alternatively, download the agreement ([Microsoft Contribution License Agreement.docx](https://www.codeplex.com/Download?ProjectName=typescript&DownloadId=822190) or [Microsoft Contribution License Agreement.pdf](https://www.codeplex.com/Download?ProjectName=typescript&DownloadId=921298)), sign, scan, and email it back to <cla@microsoft.com>. Be sure to include your github user name along with the agreement. Once we have received the signed CLA, we'll review the request. Please note that we're currently only accepting pull requests of bug fixes rather than new features.
Please submit a Contributor License Agreement (CLA) before submitting a pull request. You may visit https://cla.microsoft.com to sign digitally. Alternatively, download the agreement ([Microsoft Contribution License Agreement.docx](https://www.codeplex.com/Download?ProjectName=typescript&DownloadId=822190) or [Microsoft Contribution License Agreement.pdf](https://www.codeplex.com/Download?ProjectName=typescript&DownloadId=921298)), sign, scan, and email it back to <cla@microsoft.com>. Be sure to include your github user name along with the agreement. Once we have received the signed CLA, we'll review the request.
## Housekeeping
Your pull request should:
+96 -16
View File
@@ -4,6 +4,7 @@ var fs = require("fs");
var os = require("os");
var path = require("path");
var child_process = require("child_process");
var Linter = require("tslint");
// Variables
var compilerDirectory = "src/compiler/";
@@ -627,10 +628,9 @@ function deleteTemporaryProjectOutput() {
var testTimeout = 20000;
desc("Runs the tests using the built run.js file. Syntax is jake runtests. Optional parameters 'host=', 'tests=[regex], reporter=[list|spec|json|<more>]', debug=true.");
task("runtests", ["tests", builtLocalDirectory], function() {
task("runtests", ["build-rules", "tests", builtLocalDirectory], function() {
cleanTestDirs();
var debug = process.env.debug || process.env.d;
host = "mocha"
tests = process.env.test || process.env.tests || process.env.t;
var light = process.env.light || false;
var testConfigFile = 'test.config';
@@ -652,9 +652,16 @@ task("runtests", ["tests", builtLocalDirectory], function() {
reporter = process.env.reporter || process.env.r || 'mocha-fivemat-progress-reporter';
// timeout normally isn't necessary but Travis-CI has been timing out on compiler baselines occasionally
// default timeout is 2sec which really should be enough, but maybe we just need a small amount longer
var cmd = host + (debug ? " --debug-brk" : "") + " -R " + reporter + tests + colors + ' -t ' + testTimeout + ' ' + run;
var cmd = "mocha" + (debug ? " --debug-brk" : "") + " -R " + reporter + tests + colors + ' -t ' + testTimeout + ' ' + run;
console.log(cmd);
exec(cmd, deleteTemporaryProjectOutput);
exec(cmd, function() {
deleteTemporaryProjectOutput();
var lint = jake.Task['lint'];
lint.addListener('complete', function () {
complete();
});
lint.invoke();
});
}, {async: true});
desc("Generates code coverage data via instanbul");
@@ -812,7 +819,6 @@ task("update-sublime", ["local", serverFile], function() {
var tslintRuleDir = "scripts/tslint";
var tslintRules = ([
"nextLineRule",
"noInferrableTypesRule",
"noNullRule",
"booleanTriviaRule"
]);
@@ -825,20 +831,94 @@ var tslintRulesOutFiles = tslintRules.map(function(p) {
desc("Compiles tslint rules to js");
task("build-rules", tslintRulesOutFiles);
tslintRulesFiles.forEach(function(ruleFile, i) {
compileFile(tslintRulesOutFiles[i], [ruleFile], [ruleFile], [], /*useBuiltCompiler*/ true, /*noOutFile*/ true, /*generateDeclarations*/ false, path.join(builtLocalDirectory, "tslint"));
compileFile(tslintRulesOutFiles[i], [ruleFile], [ruleFile], [], /*useBuiltCompiler*/ false, /*noOutFile*/ true, /*generateDeclarations*/ false, path.join(builtLocalDirectory, "tslint"));
});
// if the codebase were free of linter errors we could make jake runtests
// run this task automatically
function getLinterOptions() {
return {
configuration: require("./tslint.json"),
formatter: "prose",
formattersDirectory: undefined,
rulesDirectory: "built/local/tslint"
};
}
function lintFileContents(options, path, contents) {
var ll = new Linter(path, contents, options);
return ll.lint();
}
function lintFile(options, path) {
var contents = fs.readFileSync(path, "utf8");
return lintFileContents(options, path, contents);
}
function lintFileAsync(options, path, cb) {
fs.readFile(path, "utf8", function(err, contents) {
if (err) {
return cb(err);
}
var result = lintFileContents(options, path, contents);
cb(undefined, result);
});
}
var lintTargets = compilerSources.concat(harnessCoreSources);
desc("Runs tslint on the compiler sources");
task("lint", ["build-rules"], function() {
function success(f) { return function() { console.log('SUCCESS: No linter errors in ' + f + '\n'); }};
function failure(f) { return function() { console.log('FAILURE: Please fix linting errors in ' + f + '\n') }};
var lintTargets = compilerSources.concat(harnessCoreSources);
var lintOptions = getLinterOptions();
for (var i in lintTargets) {
var f = lintTargets[i];
var cmd = 'tslint --rules-dir built/local/tslint -c tslint.json ' + f;
exec(cmd, success(f), failure(f));
var result = lintFile(lintOptions, lintTargets[i]);
if (result.failureCount > 0) {
console.log(result.output);
fail('Linter errors.', result.failureCount);
}
}
}, { async: true });
});
/**
* This is required because file watches on Windows get fires _twice_
* when a file changes on some node/windows version configuations
* (node v4 and win 10, for example). By not running a lint for a file
* which already has a pending lint, we avoid duplicating our work.
* (And avoid printing duplicate results!)
*/
var lintSemaphores = {};
function lintWatchFile(filename) {
fs.watch(filename, {persistent: true}, function(event) {
if (event !== "change") {
return;
}
if (!lintSemaphores[filename]) {
lintSemaphores[filename] = true;
lintFileAsync(getLinterOptions(), filename, function(err, result) {
delete lintSemaphores[filename];
if (err) {
console.log(err);
return;
}
if (result.failureCount > 0) {
console.log("***Lint failure***");
for (var i = 0; i < result.failures.length; i++) {
var failure = result.failures[i];
var start = failure.startPosition.lineAndCharacter;
var end = failure.endPosition.lineAndCharacter;
console.log("warning " + filename + " (" + (start.line + 1) + "," + (start.character + 1) + "," + (end.line + 1) + "," + (end.character + 1) + "): " + failure.failure);
}
console.log("*** Total " + result.failureCount + " failures.");
}
});
}
});
}
desc("Watches files for changes to rerun a lint pass");
task("lint-server", ["build-rules"], function() {
console.log("Watching ./src for changes to linted files");
for (var i = 0; i < lintTargets.length; i++) {
lintWatchFile(lintTargets[i]);
}
});
+4 -1
View File
@@ -44,7 +44,10 @@
"build": "npm run build:compiler && npm run build:tests",
"build:compiler": "jake local",
"build:tests": "jake tests",
"clean": "jake clean"
"clean": "jake clean",
"jake": "jake",
"lint": "jake lint",
"setup-hooks": "node scripts/link-hooks.js"
},
"browser": {
"buffer": false,
+2
View File
@@ -0,0 +1,2 @@
#!/bin/sh
npm run jake -- generate-diagnostics
+20
View File
@@ -0,0 +1,20 @@
var fs = require("fs");
var path = require("path");
var hooks = [
"post-checkout"
];
hooks.forEach(function (hook) {
var hookInSourceControl = path.resolve(__dirname, "hooks", hook);
if (fs.existsSync(hookInSourceControl)) {
var hookInHiddenDirectory = path.resolve(__dirname, "..", ".git", "hooks", hook);
if (fs.existsSync(hookInHiddenDirectory)) {
fs.unlinkSync(hookInHiddenDirectory);
}
fs.linkSync(hookInSourceControl, hookInHiddenDirectory);
}
});
+5 -5
View File
@@ -5,8 +5,8 @@ const OPTION_CATCH = "check-catch";
const OPTION_ELSE = "check-else";
export class Rule extends Lint.Rules.AbstractRule {
public static CATCH_FAILURE_STRING = "'catch' should be on the line following the previous block's ending curly brace";
public static ELSE_FAILURE_STRING = "'else' should be on the line following the previous block's ending curly brace";
public static CATCH_FAILURE_STRING = "'catch' should not be on the same line as the preceeding block's curly brace";
public static ELSE_FAILURE_STRING = "'else' should not be on the same line as the preceeding block's curly brace";
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
return this.applyWithWalker(new NextLineWalker(sourceFile, this.getOptions()));
@@ -25,7 +25,7 @@ class NextLineWalker extends Lint.RuleWalker {
if (this.hasOption(OPTION_ELSE) && !!elseKeyword) {
const thenStatementEndLoc = sourceFile.getLineAndCharacterOfPosition(thenStatement.getEnd());
const elseKeywordLoc = sourceFile.getLineAndCharacterOfPosition(elseKeyword.getStart(sourceFile));
if (thenStatementEndLoc.line !== (elseKeywordLoc.line - 1)) {
if (thenStatementEndLoc.line === elseKeywordLoc.line) {
const failure = this.createFailure(elseKeyword.getStart(sourceFile), elseKeyword.getWidth(sourceFile), Rule.ELSE_FAILURE_STRING);
this.addFailure(failure);
}
@@ -47,7 +47,7 @@ class NextLineWalker extends Lint.RuleWalker {
const catchKeyword = catchClause.getFirstToken(sourceFile);
const tryClosingBraceLoc = sourceFile.getLineAndCharacterOfPosition(tryClosingBrace.getEnd());
const catchKeywordLoc = sourceFile.getLineAndCharacterOfPosition(catchKeyword.getStart(sourceFile));
if (tryClosingBraceLoc.line !== (catchKeywordLoc.line - 1)) {
if (tryClosingBraceLoc.line === catchKeywordLoc.line) {
const failure = this.createFailure(catchKeyword.getStart(sourceFile), catchKeyword.getWidth(sourceFile), Rule.CATCH_FAILURE_STRING);
this.addFailure(failure);
}
@@ -58,4 +58,4 @@ class NextLineWalker extends Lint.RuleWalker {
function getFirstChildOfKind(node: ts.Node, kind: ts.SyntaxKind) {
return node.getChildren().filter((child) => child.kind === kind)[0];
}
}
-49
View File
@@ -1,49 +0,0 @@
/// <reference path="../../node_modules/tslint/typings/typescriptServices.d.ts" />
/// <reference path="../../node_modules/tslint/lib/tslint.d.ts" />
export class Rule extends Lint.Rules.AbstractRule {
public static FAILURE_STRING_FACTORY = (type: string) => `LHS type (${type}) inferred by RHS expression, remove type annotation`;
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
return this.applyWithWalker(new InferrableTypeWalker(sourceFile, this.getOptions()));
}
}
class InferrableTypeWalker extends Lint.RuleWalker {
visitVariableStatement(node: ts.VariableStatement) {
node.declarationList.declarations.forEach(e => {
if ((!!e.type) && (!!e.initializer)) {
let failure: string;
switch (e.type.kind) {
case ts.SyntaxKind.BooleanKeyword:
if (e.initializer.kind === ts.SyntaxKind.TrueKeyword || e.initializer.kind === ts.SyntaxKind.FalseKeyword) {
failure = 'boolean';
}
break;
case ts.SyntaxKind.NumberKeyword:
if (e.initializer.kind === ts.SyntaxKind.NumericLiteral) {
failure = 'number';
}
break;
case ts.SyntaxKind.StringKeyword:
switch (e.initializer.kind) {
case ts.SyntaxKind.StringLiteral:
case ts.SyntaxKind.NoSubstitutionTemplateLiteral:
case ts.SyntaxKind.TemplateExpression:
failure = 'string';
break;
default:
break;
}
break;
}
if (failure) {
this.addFailure(this.createFailure(e.type.getStart(), e.type.getWidth(), Rule.FAILURE_STRING_FACTORY(failure)));
}
}
});
super.visitVariableStatement(node);
}
}
+12 -1
View File
@@ -88,6 +88,7 @@ namespace ts {
let container: Node;
let blockScopeContainer: Node;
let lastContainer: Node;
let seenThisKeyword: boolean;
// If this file is an external module, then it is automatically in strict-mode according to
// ES6. If it is not an external module, then we'll determine if it is in strict mode or
@@ -329,7 +330,14 @@ namespace ts {
blockScopeContainer.locals = undefined;
}
forEachChild(node, bind);
if (node.kind === SyntaxKind.InterfaceDeclaration) {
seenThisKeyword = false;
forEachChild(node, bind);
node.flags = seenThisKeyword ? node.flags | NodeFlags.ContainsThis : node.flags & ~NodeFlags.ContainsThis;
}
else {
forEachChild(node, bind);
}
container = saveContainer;
parent = saveParent;
@@ -851,6 +859,9 @@ namespace ts {
return checkStrictModePrefixUnaryExpression(<PrefixUnaryExpression>node);
case SyntaxKind.WithStatement:
return checkStrictModeWithStatement(<WithStatement>node);
case SyntaxKind.ThisKeyword:
seenThisKeyword = true;
return;
case SyntaxKind.TypeParameter:
return declareSymbolAndAddToSymbolTable(<Declaration>node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes);
+398 -211
View File
File diff suppressed because it is too large Load Diff
+5 -4
View File
@@ -76,10 +76,11 @@ namespace ts {
"amd": ModuleKind.AMD,
"system": ModuleKind.System,
"umd": ModuleKind.UMD,
"es6": ModuleKind.ES6,
},
description: Diagnostics.Specify_module_code_generation_Colon_commonjs_amd_system_or_umd,
description: Diagnostics.Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es6,
paramType: Diagnostics.KIND,
error: Diagnostics.Argument_for_module_option_must_be_commonjs_amd_system_or_umd
error: Diagnostics.Argument_for_module_option_must_be_commonjs_amd_system_umd_or_es6
},
{
name: "newLine",
@@ -340,7 +341,7 @@ namespace ts {
}
}
}
function parseResponseFile(fileName: string) {
let text = readFile ? readFile(fileName) : sys.readFile(fileName);
@@ -546,7 +547,7 @@ namespace ts {
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"));
errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "files", "Array"));
}
}
else {
+6 -6
View File
@@ -52,7 +52,7 @@ namespace ts {
function normalizeKey(key: string) {
return getCanonicalFileName(normalizeSlashes(key));
}
function clear() {
files = {};
}
@@ -117,7 +117,7 @@ namespace ts {
return count;
}
export function filter<T>(array: T[], f: (x: T) => boolean): T[]{
export function filter<T>(array: T[], f: (x: T) => boolean): T[] {
let result: T[];
if (array) {
result = [];
@@ -130,7 +130,7 @@ namespace ts {
return result;
}
export function map<T, U>(array: T[], f: (x: T) => U): U[]{
export function map<T, U>(array: T[], f: (x: T) => U): U[] {
let result: U[];
if (array) {
result = [];
@@ -148,7 +148,7 @@ namespace ts {
return array1.concat(array2);
}
export function deduplicate<T>(array: T[]): T[]{
export function deduplicate<T>(array: T[]): T[] {
let result: T[];
if (array) {
result = [];
@@ -486,7 +486,7 @@ namespace ts {
return text1 ? Comparison.GreaterThan : Comparison.LessThan;
}
export function sortAndDeduplicateDiagnostics(diagnostics: Diagnostic[]): Diagnostic[]{
export function sortAndDeduplicateDiagnostics(diagnostics: Diagnostic[]): Diagnostic[] {
return deduplicateSortedDiagnostics(diagnostics.sort(compareDiagnostics));
}
@@ -795,7 +795,7 @@ namespace ts {
VeryAggressive = 3,
}
export module Debug {
export namespace Debug {
let currentAssertionLevel = AssertionLevel.None;
export function shouldAssert(level: AssertionLevel): boolean {
+19 -3
View File
@@ -52,6 +52,7 @@ namespace ts {
let enclosingDeclaration: Node;
let currentSourceFile: SourceFile;
let reportedDeclarationError = false;
let errorNameNode: DeclarationName;
let emitJsDocComments = compilerOptions.removeComments ? function (declaration: Node) { } : writeJsDocComments;
let emit = compilerOptions.stripInternal ? stripInternal : emitNode;
@@ -164,6 +165,7 @@ namespace ts {
function createAndSetNewTextWriterWithSymbolWriter(): EmitTextWriterWithSymbolWriter {
let writer = <EmitTextWriterWithSymbolWriter>createTextWriter(newLine);
writer.trackSymbol = trackSymbol;
writer.reportInaccessibleThisError = reportInaccessibleThisError;
writer.writeKeyword = writer.write;
writer.writeOperator = writer.write;
writer.writePunctuation = writer.write;
@@ -190,9 +192,11 @@ namespace ts {
let nodeToCheck: Node;
if (declaration.kind === SyntaxKind.VariableDeclaration) {
nodeToCheck = declaration.parent.parent;
} else if (declaration.kind === SyntaxKind.NamedImports || declaration.kind === SyntaxKind.ImportSpecifier || declaration.kind === SyntaxKind.ImportClause) {
}
else if (declaration.kind === SyntaxKind.NamedImports || declaration.kind === SyntaxKind.ImportSpecifier || declaration.kind === SyntaxKind.ImportClause) {
Debug.fail("We should be getting ImportDeclaration instead to write");
} else {
}
else {
nodeToCheck = declaration;
}
@@ -269,6 +273,13 @@ namespace ts {
handleSymbolAccessibilityError(resolver.isSymbolAccessible(symbol, enclosingDeclaration, meaning));
}
function reportInaccessibleThisError() {
if (errorNameNode) {
diagnostics.push(createDiagnosticForNode(errorNameNode, Diagnostics.The_inferred_type_of_0_references_an_inaccessible_this_type_A_type_annotation_is_necessary,
declarationNameToString(errorNameNode)));
}
}
function writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, type: TypeNode, getSymbolAccessibilityDiagnostic: GetSymbolAccessibilityDiagnostic) {
writer.getSymbolAccessibilityDiagnostic = getSymbolAccessibilityDiagnostic;
write(": ");
@@ -277,7 +288,9 @@ namespace ts {
emitType(type);
}
else {
errorNameNode = declaration.name;
resolver.writeTypeOfDeclaration(declaration, enclosingDeclaration, TypeFormatFlags.UseTypeOfFunction, writer);
errorNameNode = undefined;
}
}
@@ -289,7 +302,9 @@ namespace ts {
emitType(signature.type);
}
else {
errorNameNode = signature.name;
resolver.writeReturnTypeOfSignatureDeclaration(signature, enclosingDeclaration, TypeFormatFlags.UseTypeOfFunction, writer);
errorNameNode = undefined;
}
}
@@ -338,6 +353,7 @@ namespace ts {
case SyntaxKind.BooleanKeyword:
case SyntaxKind.SymbolKeyword:
case SyntaxKind.VoidKeyword:
case SyntaxKind.ThisKeyword:
case SyntaxKind.StringLiteral:
return writeTextOfNode(currentSourceFile, type);
case SyntaxKind.ExpressionWithTypeArguments:
@@ -1080,7 +1096,7 @@ namespace ts {
// emitted: declare var c: number; // instead of declare var c:number, ;
let elements: Node[] = [];
for (let element of bindingPattern.elements) {
if (element.kind !== SyntaxKind.OmittedExpression){
if (element.kind !== SyntaxKind.OmittedExpression) {
elements.push(element);
}
}
+15 -11
View File
@@ -195,7 +195,7 @@
"category": "Error",
"code": 1063
},
"Ambient enum elements can only have integer literal initializers.": {
"In ambient enum declarations member initializer must be constant expression.": {
"category": "Error",
"code": 1066
},
@@ -619,22 +619,18 @@
"category": "Error",
"code": 1200
},
"Import assignment cannot be used when targeting ECMAScript 6 or higher. Consider using 'import * as ns from \"mod\"', 'import {a} from \"mod\"' or 'import d from \"mod\"' instead.": {
"Import assignment cannot be used when targeting ECMAScript 6 modules. Consider using 'import * as ns from \"mod\"', 'import {a} from \"mod\"', 'import d from \"mod\"', or another module format instead.": {
"category": "Error",
"code": 1202
},
"Export assignment cannot be used when targeting ECMAScript 6 or higher. Consider using 'export default' instead.": {
"Export assignment cannot be used when targeting ECMAScript 6 modules. Consider using 'export default' or another module format instead.": {
"category": "Error",
"code": 1203
},
"Cannot compile modules into 'commonjs', 'amd', 'system' or 'umd' when targeting 'ES6' or higher.": {
"Cannot compile modules into 'es6' when targeting 'ES5' or lower.": {
"category": "Error",
"code": 1204
},
"Decorators are only available when targeting ECMAScript 5 and higher.": {
"category": "Error",
"code": 1205
},
"Decorators are not valid here.": {
"category": "Error",
"code": 1206
@@ -1300,7 +1296,7 @@
"category": "Error",
"code": 2434
},
"Ambient modules cannot be nested in other modules.": {
"Ambient modules cannot be nested in other modules or namespaces.": {
"category": "Error",
"code": 2435
},
@@ -1652,6 +1648,14 @@
"category": "Error",
"code": 2525
},
"A 'this' type is available only in a non-static member of a class or interface.": {
"category": "Error",
"code": 2526
},
"The inferred type of '{0}' references an inaccessible 'this' type. A type annotation is necessary.": {
"category": "Error",
"code": 2527
},
"JSX element attributes type '{0}' must be an object type.": {
"category": "Error",
"code": 2600
@@ -2105,7 +2109,7 @@
"category": "Message",
"code": 6015
},
"Specify module code generation: 'commonjs', 'amd', 'system' or 'umd'": {
"Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es6'": {
"category": "Message",
"code": 6016
},
@@ -2193,7 +2197,7 @@
"category": "Error",
"code": 6045
},
"Argument for '--module' option must be 'commonjs', 'amd', 'system' or 'umd'.": {
"Argument for '--module' option must be 'commonjs', 'amd', 'system', 'umd', or 'es6'.": {
"category": "Error",
"code": 6046
},
+406 -395
View File
File diff suppressed because it is too large Load Diff
+25 -14
View File
@@ -425,7 +425,7 @@ namespace ts {
// Implement the parser as a singleton module. We do this for perf reasons because creating
// parser instances can actually be expensive enough to impact us on projects with many source
// files.
module Parser {
namespace Parser {
// Share a single scanner across all calls to parse a source file. This helps speed things
// up by avoiding the cost of creating/compiling scanners over and over again.
const scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ true);
@@ -518,7 +518,7 @@ namespace ts {
//
// Note: any errors at the end of the file that do not precede a regular node, should get
// attached to the EOF token.
let parseErrorBeforeNextFinishedNode: boolean = false;
let parseErrorBeforeNextFinishedNode = false;
export function parseSourceFile(fileName: string, _sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, setParentNodes?: boolean): SourceFile {
initializeState(fileName, _sourceText, languageVersion, _syntaxCursor);
@@ -860,7 +860,7 @@ namespace ts {
let saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode;
// Note: it is not actually necessary to save/restore the context flags here. That's
// because the saving/restorating of these flags happens naturally through the recursive
// because the saving/restoring of these flags happens naturally through the recursive
// descent nature of our parser. However, we still store this here just so we can
// assert that that invariant holds.
let saveContextFlags = contextFlags;
@@ -1128,7 +1128,15 @@ namespace ts {
if (token === SyntaxKind.DefaultKeyword) {
return nextTokenIsClassOrFunction();
}
if (token === SyntaxKind.StaticKeyword) {
nextToken();
return canFollowModifier();
}
nextToken();
if (scanner.hasPrecedingLineBreak()) {
return false;
}
return canFollowModifier();
}
@@ -2364,6 +2372,7 @@ namespace ts {
let node = tryParse(parseKeywordAndNoDot);
return node || parseTypeReferenceOrTypePredicate();
case SyntaxKind.VoidKeyword:
case SyntaxKind.ThisKeyword:
return parseTokenNode<TypeNode>();
case SyntaxKind.TypeOfKeyword:
return parseTypeQuery();
@@ -2386,6 +2395,7 @@ namespace ts {
case SyntaxKind.BooleanKeyword:
case SyntaxKind.SymbolKeyword:
case SyntaxKind.VoidKeyword:
case SyntaxKind.ThisKeyword:
case SyntaxKind.TypeOfKeyword:
case SyntaxKind.OpenBraceToken:
case SyntaxKind.OpenBracketToken:
@@ -3942,7 +3952,8 @@ namespace ts {
forOfStatement.expression = allowInAnd(parseAssignmentExpressionOrHigher);
parseExpected(SyntaxKind.CloseParenToken);
forOrForInOrForOfStatement = forOfStatement;
} else {
}
else {
let forStatement = <ForStatement>createNode(SyntaxKind.ForStatement, pos);
forStatement.initializer = initializer;
parseExpected(SyntaxKind.SemicolonToken);
@@ -4158,8 +4169,12 @@ namespace ts {
case SyntaxKind.ModuleKeyword:
case SyntaxKind.NamespaceKeyword:
return nextTokenIsIdentifierOrStringLiteralOnSameLine();
case SyntaxKind.AbstractKeyword:
case SyntaxKind.AsyncKeyword:
case SyntaxKind.DeclareKeyword:
case SyntaxKind.PrivateKeyword:
case SyntaxKind.ProtectedKeyword:
case SyntaxKind.PublicKeyword:
nextToken();
// ASI takes effect for this modifier.
if (scanner.hasPrecedingLineBreak()) {
@@ -4179,11 +4194,7 @@ namespace ts {
}
continue;
case SyntaxKind.PublicKeyword:
case SyntaxKind.PrivateKeyword:
case SyntaxKind.ProtectedKeyword:
case SyntaxKind.StaticKeyword:
case SyntaxKind.AbstractKeyword:
nextToken();
continue;
default:
@@ -4829,7 +4840,7 @@ namespace ts {
return finishNode(node);
}
function parseNameOfClassDeclarationOrExpression(): Identifier {
// implements is a future reserved word so
// 'class implements' might mean either
@@ -4840,11 +4851,11 @@ namespace ts {
? parseIdentifier()
: undefined;
}
function isImplementsClause() {
return token === SyntaxKind.ImplementsKeyword && lookAhead(nextTokenIsIdentifierOrKeyword)
return token === SyntaxKind.ImplementsKeyword && lookAhead(nextTokenIsIdentifierOrKeyword);
}
function parseHeritageClauses(isClassHeritageClause: boolean): NodeArray<HeritageClause> {
// ClassTail[Yield,Await] : (Modified) See 14.5
// ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt }
@@ -5319,7 +5330,7 @@ namespace ts {
Unknown
}
export module JSDocParser {
export namespace JSDocParser {
export function isJSDocType() {
switch (token) {
case SyntaxKind.AsteriskToken:
@@ -5964,7 +5975,7 @@ namespace ts {
}
}
module IncrementalParser {
namespace IncrementalParser {
export function updateSourceFile(sourceFile: SourceFile, newText: string, textChangeRange: TextChangeRange, aggressiveChecks: boolean): SourceFile {
aggressiveChecks = aggressiveChecks || Debug.shouldAssert(AssertionLevel.Aggressive);
+132 -125
View File
@@ -9,9 +9,9 @@ namespace ts {
/* @internal */ export let ioWriteTime = 0;
/** The version of the TypeScript compiler release */
let emptyArray: any[] = [];
export const version = "1.7.0";
export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean): string {
@@ -29,36 +29,36 @@ 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): ResolvedModuleWithFailedLookupLocations {
let moduleResolution = compilerOptions.moduleResolution !== undefined
let moduleResolution = compilerOptions.moduleResolution !== undefined
? compilerOptions.moduleResolution
: compilerOptions.module === ModuleKind.CommonJS ? ModuleResolutionKind.NodeJs : ModuleResolutionKind.Classic;
switch (moduleResolution) {
case ModuleResolutionKind.NodeJs: return nodeModuleNameResolver(moduleName, containingFile, getSupportedExtensions(compilerOptions), host);
case ModuleResolutionKind.Classic: return classicNameResolver(moduleName, containingFile, compilerOptions, host);
}
}
export function nodeModuleNameResolver(moduleName: string, containingFile: string, supportedExtensions: string[], host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
let containingDirectory = getDirectoryPath(containingFile);
let containingDirectory = getDirectoryPath(containingFile);
if (getRootLength(moduleName) !== 0 || nameStartsWithDotSlashOrDotDotSlash(moduleName)) {
let failedLookupLocations: string[] = [];
let candidate = normalizePath(combinePaths(containingDirectory, moduleName));
let resolvedFileName = loadNodeModuleFromFile(candidate, supportedExtensions, failedLookupLocations, host);
if (resolvedFileName) {
return { resolvedModule: { resolvedFileName }, failedLookupLocations };
}
resolvedFileName = loadNodeModuleFromDirectory(candidate, supportedExtensions, failedLookupLocations, host);
return resolvedFileName
? { resolvedModule: { resolvedFileName }, failedLookupLocations }
@@ -68,10 +68,10 @@ namespace ts {
return loadModuleFromNodeModules(moduleName, containingDirectory, host);
}
}
function loadNodeModuleFromFile(candidate: string, supportedExtensions: string[], failedLookupLocation: string[], host: ModuleResolutionHost): string {
return forEach(supportedExtensions, tryLoad);
function tryLoad(ext: string): string {
let fileName = fileExtensionIs(candidate, ext) ? candidate : candidate + "." + ext;
if (host.fileExists(fileName)) {
@@ -83,13 +83,13 @@ namespace ts {
}
}
}
function loadNodeModuleFromDirectory(candidate: string, supportedExtensions: string[], failedLookupLocation: string[], host: ModuleResolutionHost): string {
let packageJsonPath = combinePaths(candidate, "package.json");
if (host.fileExists(packageJsonPath)) {
let jsonContent: { typings?: string };
try {
let jsonText = host.readFile(packageJsonPath);
jsonContent = jsonText ? <{ typings?: string }>JSON.parse(jsonText) : { typings: undefined };
@@ -98,7 +98,7 @@ namespace ts {
// gracefully handle if readFile fails or returns not JSON
jsonContent = { typings: undefined };
}
if (jsonContent.typings) {
let result = loadNodeModuleFromFile(normalizePath(combinePaths(candidate, jsonContent.typings)), supportedExtensions, failedLookupLocation, host);
if (result) {
@@ -110,12 +110,12 @@ namespace ts {
// record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results
failedLookupLocation.push(packageJsonPath);
}
return loadNodeModuleFromFile(combinePaths(candidate, "index"), supportedExtensions, failedLookupLocation, host);
}
function loadModuleFromNodeModules(moduleName: string, directory: string, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
let failedLookupLocations: string[] = [];
let failedLookupLocations: string[] = [];
directory = normalizeSlashes(directory);
while (true) {
let baseName = getBaseFileName(directory);
@@ -126,36 +126,36 @@ namespace ts {
if (result) {
return { resolvedModule: { resolvedFileName: result, isExternalLibraryImport: true }, failedLookupLocations };
}
result = loadNodeModuleFromDirectory(candidate, /* loadOnlyDts */ ["d.ts"], failedLookupLocations, host);
if (result) {
return { resolvedModule: { resolvedFileName: result, isExternalLibraryImport: true }, failedLookupLocations };
}
}
let parentPath = getDirectoryPath(directory);
if (parentPath === directory) {
break;
}
directory = parentPath;
}
return { resolvedModule: undefined, failedLookupLocations };
}
function nameStartsWithDotSlashOrDotDotSlash(name: string) {
let i = name.lastIndexOf("./", 1);
return i === 0 || (i === 1 && name.charCodeAt(0) === CharacterCodes.dot);
}
export function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
// module names that contain '!' are used to reference resources and are not resolved to actual files on disk
if (moduleName.indexOf('!') != -1) {
if (moduleName.indexOf("!") != -1) {
return { resolvedModule: undefined, failedLookupLocations: [] };
}
let searchPath = getDirectoryPath(containingFile);
let searchName: string;
@@ -170,7 +170,7 @@ namespace ts {
// 'logical not' handles both undefined and None cases
return undefined;
}
let candidate = searchName + "." + extension;
if (host.fileExists(candidate)) {
return candidate;
@@ -272,8 +272,7 @@ namespace ts {
}
const newLine = getNewLineCharacter(options);
return {
getSourceFile,
getDefaultLibFileName: options => combinePaths(getDirectoryPath(normalizePath(sys.getExecutingFilePath())), getDefaultLibFileName(options)),
@@ -342,27 +341,27 @@ namespace ts {
let start = new Date().getTime();
host = host || createCompilerHost(options);
const resolveModuleNamesWorker = host.resolveModuleNames
? ((moduleNames: string[], containingFile: string) => host.resolveModuleNames(moduleNames, containingFile))
: ((moduleNames: string[], containingFile: string) => map(moduleNames, moduleName => resolveModuleName(moduleName, containingFile, options, host).resolvedModule));
let filesByName = createFileMap<SourceFile>(fileName => host.getCanonicalFileName(fileName));
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) ||
if ((oldOptions.module !== options.module) ||
(oldOptions.noResolve !== options.noResolve) ||
(oldOptions.target !== options.target) ||
(oldOptions.noLib !== options.noLib) ||
(oldOptions.jsx !== options.jsx) ||
(oldOptions.jsx !== options.jsx) ||
(oldOptions.jsExtensions !== options.jsExtensions)) {
oldProgram = undefined;
}
}
if (!tryReuseStructureFromOldProgram()) {
let supportedExtensions = getSupportedExtensions(options);
forEach(rootNames, name => processRootFile(name, false, supportedExtensions));
@@ -424,7 +423,7 @@ namespace ts {
if (!oldProgram) {
return false;
}
Debug.assert(!oldProgram.structureIsReused);
// there is an old program, check if we can reuse its structure
@@ -432,7 +431,7 @@ namespace ts {
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[] = [];
let modifiedSourceFiles: SourceFile[] = [];
@@ -442,7 +441,7 @@ namespace ts {
return false;
}
if (oldSourceFile !== newSourceFile) {
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
@@ -454,14 +453,14 @@ namespace ts {
// 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);
@@ -470,11 +469,11 @@ namespace ts {
let newResolution = resolutions[i];
let oldResolution = getResolvedModule(oldSourceFile, moduleNames[i]);
let resolutionChanged = oldResolution
? !newResolution ||
? !newResolution ||
oldResolution.resolvedFileName !== newResolution.resolvedFileName ||
!!oldResolution.isExternalLibraryImport !== !!newResolution.isExternalLibraryImport
: newResolution;
if (resolutionChanged) {
return false;
}
@@ -488,24 +487,24 @@ namespace ts {
// 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;
fileProcessingDiagnostics = oldProgram.getFileProcessingDiagnostics();
for (let modifiedFile of modifiedSourceFiles) {
fileProcessingDiagnostics.reattachFileDiagnostics(modifiedFile);
}
oldProgram.structureIsReused = true;
return true;
}
@@ -551,7 +550,7 @@ namespace ts {
// This is because in the -out scenario all files need to be emitted, and therefore all
// files need to be type checked. And the way to specify that all files need to be type
// checked is to not pass the file to getEmitResolver.
let emitResolver = getDiagnosticsProducingTypeChecker().getEmitResolver((options.outFile || options.out)? undefined : sourceFile);
let emitResolver = getDiagnosticsProducingTypeChecker().getEmitResolver((options.outFile || options.out) ? undefined : sourceFile);
let start = new Date().getTime();
@@ -565,7 +564,9 @@ namespace ts {
}
function getSourceFile(fileName: string) {
return filesByName.get(fileName);
// first try to use file name as is to find file
// then try to convert relative file name to absolute and use it to retrieve source file
return filesByName.get(fileName) || filesByName.get(getNormalizedAbsolutePath(fileName, host.getCurrentDirectory()));
}
function getDiagnosticsHelper(
@@ -736,7 +737,7 @@ namespace ts {
return true;
}
if (parameter.questionToken) {
diagnostics.push(createDiagnosticForNode(parameter.questionToken, Diagnostics._0_can_only_be_used_in_a_ts_file, '?'));
diagnostics.push(createDiagnosticForNode(parameter.questionToken, Diagnostics._0_can_only_be_used_in_a_ts_file, "?"));
return true;
}
if (parameter.type) {
@@ -819,7 +820,7 @@ namespace ts {
function getOptionsDiagnostics(): Diagnostic[] {
let allDiagnostics: Diagnostic[] = [];
addRange(allDiagnostics, fileProcessingDiagnostics.getGlobalDiagnostics())
addRange(allDiagnostics, fileProcessingDiagnostics.getGlobalDiagnostics());
addRange(allDiagnostics, programDiagnostics.getGlobalDiagnostics());
return sortAndDeduplicateDiagnostics(allDiagnostics);
}
@@ -830,25 +831,35 @@ namespace ts {
return sortAndDeduplicateDiagnostics(allDiagnostics);
}
function hasExtension(fileName: string): boolean {
return getBaseFileName(fileName).indexOf(".") >= 0;
}
function processRootFile(fileName: string, isDefaultLib: boolean, supportedExtensions: string[]) {
processSourceFile(normalizePath(fileName), isDefaultLib, supportedExtensions);
}
}
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) {
collect(node, /* allowRelativeModuleNames */ true);
}
file.imports = imports || emptyArray;
function collect(node: Node, allowRelativeModuleNames: boolean): void {
switch (node.kind) {
case SyntaxKind.ImportDeclaration:
case SyntaxKind.ImportEqualsDeclaration:
@@ -861,7 +872,9 @@ namespace ts {
break;
}
(imports || (imports = [])).push(<LiteralExpression>moduleNameExpr);
if (allowRelativeModuleNames || !isExternalModuleNameRelative((<LiteralExpression>moduleNameExpr).text)) {
(imports || (imports = [])).push(<LiteralExpression>moduleNameExpr);
}
break;
case SyntaxKind.ModuleDeclaration:
if ((<ModuleDeclaration>node).name.kind === SyntaxKind.StringLiteral && (node.flags & NodeFlags.Ambient || isDeclarationFile(file))) {
@@ -871,23 +884,15 @@ namespace ts {
// 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);
}
}
// 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.
collect(node, /* allowRelativeModuleNames */ false);
});
}
break;
}
}
file.imports = imports || emptyArray;
}
function processSourceFile(fileName: string, isDefaultLib: boolean, supportedExtensions: string[], refFile?: SourceFile, refPos?: number, refEnd?: number) {
@@ -916,7 +921,7 @@ namespace ts {
}
else if (!forEach(getSupportedExtensions(options), extension => findSourceFile(fileName + "." + extension, isDefaultLib, supportedExtensions, refFile, refPos, refEnd))) {
// (TODO: shkamat) Should this message be different given we support multiple extensions
diagnostic = Diagnostics.File_0_not_found;
diagnostic = Diagnostics.File_0_not_found;
fileName += ".ts";
diagnosticArgument = [fileName];
}
@@ -935,60 +940,62 @@ namespace ts {
// Get source file from normalized fileName
function findSourceFile(fileName: string, isDefaultLib: boolean, supportedExtensions: string[], refFile?: SourceFile, refPos?: number, refEnd?: number): SourceFile {
let canonicalName = host.getCanonicalFileName(normalizeSlashes(fileName));
if (filesByName.contains(canonicalName)) {
if (filesByName.contains(fileName)) {
// We've already looked for this file, use cached result
return getSourceFileFromCache(fileName, canonicalName, /*useAbsolutePath*/ false);
return getSourceFileFromCache(fileName, /*useAbsolutePath*/ false);
}
else {
let normalizedAbsolutePath = getNormalizedAbsolutePath(fileName, host.getCurrentDirectory());
let canonicalAbsolutePath = host.getCanonicalFileName(normalizedAbsolutePath);
if (filesByName.contains(canonicalAbsolutePath)) {
return getSourceFileFromCache(normalizedAbsolutePath, canonicalAbsolutePath, /*useAbsolutePath*/ true);
}
// We haven't looked for this file, do so now and cache result
let file = host.getSourceFile(fileName, options.target, hostErrorMessage => {
if (refFile !== undefined && refPos !== undefined && refEnd !== undefined) {
fileProcessingDiagnostics.add(createFileDiagnostic(refFile, refPos, refEnd - refPos,
Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage));
}
else {
fileProcessingDiagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage));
}
});
filesByName.set(canonicalName, file);
if (file) {
skipDefaultLib = skipDefaultLib || file.hasNoDefaultLib;
// Set the source file for normalized absolute path
filesByName.set(canonicalAbsolutePath, file);
let basePath = getDirectoryPath(fileName);
if (!options.noResolve) {
processReferencedFiles(file, basePath, supportedExtensions);
}
// always process imported modules to record module name resolutions
processImportedModules(file, basePath, supportedExtensions);
if (isDefaultLib) {
file.isDefaultLib = true;
files.unshift(file);
}
else {
files.push(file);
}
}
let normalizedAbsolutePath = getNormalizedAbsolutePath(fileName, host.getCurrentDirectory());
if (filesByName.contains(normalizedAbsolutePath)) {
const file = getSourceFileFromCache(normalizedAbsolutePath, /*useAbsolutePath*/ true);
// we don't have resolution for this relative file name but the match was found by absolute file name
// store resolution for relative name as well
filesByName.set(fileName, file);
return file;
}
function getSourceFileFromCache(fileName: string, canonicalName: string, useAbsolutePath: boolean): SourceFile {
let file = filesByName.get(canonicalName);
// We haven't looked for this file, do so now and cache result
let file = host.getSourceFile(fileName, options.target, hostErrorMessage => {
if (refFile !== undefined && refPos !== undefined && refEnd !== undefined) {
fileProcessingDiagnostics.add(createFileDiagnostic(refFile, refPos, refEnd - refPos,
Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage));
}
else {
fileProcessingDiagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage));
}
});
filesByName.set(fileName, file);
if (file) {
skipDefaultLib = skipDefaultLib || file.hasNoDefaultLib;
// Set the source file for normalized absolute path
filesByName.set(normalizedAbsolutePath, file);
let basePath = getDirectoryPath(fileName);
if (!options.noResolve) {
processReferencedFiles(file, basePath, supportedExtensions);
}
// always process imported modules to record module name resolutions
processImportedModules(file, basePath, supportedExtensions);
if (isDefaultLib) {
file.isDefaultLib = true;
files.unshift(file);
}
else {
files.push(file);
}
}
return file;
function getSourceFileFromCache(fileName: string, useAbsolutePath: boolean): SourceFile {
let file = filesByName.get(fileName);
if (file && host.useCaseSensitiveFileNames()) {
let sourceFileName = useAbsolutePath ? getNormalizedAbsolutePath(file.fileName, host.getCurrentDirectory()) : file.fileName;
if (canonicalName !== sourceFileName) {
if (normalizeSlashes(fileName) !== normalizeSlashes(sourceFileName)) {
if (refFile !== undefined && refPos !== undefined && refEnd !== undefined) {
fileProcessingDiagnostics.add(createFileDiagnostic(refFile, refPos, refEnd - refPos,
Diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing, fileName, sourceFileName));
@@ -1008,7 +1015,7 @@ namespace ts {
processSourceFile(referencedFileName, /* isDefaultLib */ false, supportedExtensions, file, ref.pos, ref.end);
});
}
function processImportedModules(file: SourceFile, basePath: string, supportedExtensions: string[]) {
collectExternalModuleReferences(file);
if (file.imports.length) {
@@ -1022,11 +1029,11 @@ namespace ts {
const importedFile = findModuleSourceFile(resolution.resolvedFileName, file.imports[i], supportedExtensions);
if (importedFile && resolution.isExternalLibraryImport) {
if (!isExternalModule(importedFile)) {
let start = getTokenPosOfNode(file.imports[i], file)
fileProcessingDiagnostics.add(createFileDiagnostic(file, start, file.imports[i].end - start, Diagnostics.Exported_external_package_typings_file_0_is_not_a_module_Please_contact_the_package_author_to_update_the_package_definition, importedFile.fileName));
let start = getTokenPosOfNode(file.imports[i], file);
fileProcessingDiagnostics.add(createFileDiagnostic(file, start, file.imports[i].end - start, Diagnostics.Exported_external_package_typings_file_0_is_not_a_module_Please_contact_the_package_author_to_update_the_package_definition, importedFile.fileName));
}
else if (!fileExtensionIs(importedFile.fileName, "d.ts")) {
let start = getTokenPosOfNode(file.imports[i], file)
let start = getTokenPosOfNode(file.imports[i], file);
fileProcessingDiagnostics.add(createFileDiagnostic(file, start, file.imports[i].end - start, Diagnostics.Exported_external_package_typings_can_only_be_in_d_ts_files_Please_contact_the_package_author_to_update_the_package_definition));
}
else if (importedFile.referencedFiles.length) {
@@ -1182,9 +1189,9 @@ namespace ts {
programDiagnostics.add(createFileDiagnostic(firstExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_compile_modules_unless_the_module_flag_is_provided));
}
// Cannot specify module gen target when in es6 or above
if (options.module && languageVersion >= ScriptTarget.ES6) {
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_compile_modules_into_commonjs_amd_system_or_umd_when_targeting_ES6_or_higher));
// Cannot specify module gen target of es6 when below es6
if (options.module === ModuleKind.ES6 && languageVersion < ScriptTarget.ES6) {
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_compile_modules_into_es6_when_targeting_ES5_or_lower));
}
// there has to be common source directory if user specified --outdir || --sourceRoot
+5 -3
View File
@@ -224,7 +224,7 @@ namespace ts {
}
// Perform binary search in one of the Unicode range maps
let lo: number = 0;
let lo = 0;
let hi: number = map.length;
let mid: number;
@@ -657,7 +657,7 @@ 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)
@@ -1361,7 +1361,9 @@ namespace ts {
if (text.charCodeAt(pos + 1) === CharacterCodes.equals) {
return pos += 2, token = SyntaxKind.LessThanEqualsToken;
}
if (text.charCodeAt(pos + 1) === CharacterCodes.slash && languageVariant === LanguageVariant.JSX) {
if (languageVariant === LanguageVariant.JSX &&
text.charCodeAt(pos + 1) === CharacterCodes.slash &&
text.charCodeAt(pos + 2) !== CharacterCodes.asterisk) {
return pos += 2, token = SyntaxKind.LessThanSlashToken;
}
return pos++, token = SyntaxKind.LessThanToken;
+14 -9
View File
@@ -8,7 +8,7 @@ namespace ts {
write(s: string): void;
readFile(path: string, encoding?: string): string;
writeFile(path: string, data: string, writeByteOrderMark?: boolean): void;
watchFile?(path: string, callback: (path: string) => void): FileWatcher;
watchFile?(path: string, callback: (path: string, removed: boolean) => void): FileWatcher;
resolvePath(path: string): string;
fileExists(path: string): boolean;
directoryExists(path: string): boolean;
@@ -29,8 +29,8 @@ namespace ts {
declare var process: any;
declare var global: any;
declare var __filename: string;
declare var Buffer: {
new (str: string, encoding?: string): any;
declare var Buffer: {
new (str: string, encoding?: string): any;
};
declare class Enumerator {
@@ -116,7 +116,7 @@ namespace ts {
return path.toLowerCase();
}
function getNames(collection: any): string[]{
function getNames(collection: any): string[] {
let result: string[] = [];
for (let e = new Enumerator(collection); !e.atEnd(); e.moveNext()) {
result.push(e.item().Name);
@@ -270,9 +270,9 @@ namespace ts {
args: process.argv.slice(2),
newLine: _os.EOL,
useCaseSensitiveFileNames: useCaseSensitiveFileNames,
write(s: string): void {
const buffer = new Buffer(s, "utf8");
let offset: number = 0;
write(s: string): void {
const buffer = new Buffer(s, "utf8");
let offset = 0;
let toWrite: number = buffer.length;
let written = 0;
// 1 is a standard descriptor for stdout
@@ -280,7 +280,7 @@ namespace ts {
offset += written;
toWrite -= written;
}
},
},
readFile,
writeFile,
watchFile: (fileName, callback) => {
@@ -292,11 +292,16 @@ namespace ts {
};
function fileChanged(curr: any, prev: any) {
// mtime.getTime() equals 0 if file was removed
if (curr.mtime.getTime() === 0) {
callback(fileName, /* removed */ true);
return;
}
if (+curr.mtime <= +prev.mtime) {
return;
}
callback(fileName);
callback(fileName, /* removed */ false);
}
},
resolvePath: function (path: string): string {
+28 -10
View File
@@ -86,7 +86,6 @@ namespace ts {
if (diagnostic.file) {
let loc = getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start);
output += `${ diagnostic.file.fileName }(${ loc.line + 1 },${ loc.character + 1 }): `;
}
@@ -102,6 +101,19 @@ namespace ts {
}
}
function reportWatchDiagnostic(diagnostic: Diagnostic) {
let output = new Date().toLocaleTimeString() + " - ";
if (diagnostic.file) {
let loc = getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start);
output += `${ diagnostic.file.fileName }(${ loc.line + 1 },${ loc.character + 1 }): `;
}
output += `${ flattenDiagnosticMessageText(diagnostic.messageText, sys.newLine) }${ sys.newLine }`;
sys.write(output);
}
function padLeft(s: string, length: number) {
while (s.length < length) {
s = " " + s;
@@ -218,7 +230,7 @@ namespace ts {
let result = readConfigFile(configFileName, sys.readFile);
if (result.error) {
reportDiagnostic(result.error);
reportWatchDiagnostic(result.error);
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
}
@@ -247,7 +259,7 @@ namespace ts {
}
setCachedProgram(compileResult.program);
reportDiagnostic(createCompilerDiagnostic(Diagnostics.Compilation_complete_Watching_for_file_changes));
reportWatchDiagnostic(createCompilerDiagnostic(Diagnostics.Compilation_complete_Watching_for_file_changes));
}
function getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void) {
@@ -263,7 +275,7 @@ namespace ts {
let sourceFile = hostGetSourceFile(fileName, languageVersion, onError);
if (sourceFile && compilerOptions.watch) {
// Attach a file watcher
sourceFile.fileWatcher = sys.watchFile(sourceFile.fileName, () => sourceFileChanged(sourceFile));
sourceFile.fileWatcher = sys.watchFile(sourceFile.fileName, (fileName, removed) => sourceFileChanged(sourceFile, removed));
}
return sourceFile;
}
@@ -285,9 +297,15 @@ namespace ts {
}
// If a source file changes, mark it as unwatched and start the recompilation timer
function sourceFileChanged(sourceFile: SourceFile) {
function sourceFileChanged(sourceFile: SourceFile, removed: boolean) {
sourceFile.fileWatcher.close();
sourceFile.fileWatcher = undefined;
if (removed) {
let index = rootFileNames.indexOf(sourceFile.fileName);
if (index >= 0) {
rootFileNames.splice(index, 1);
}
}
startTimer();
}
@@ -309,7 +327,7 @@ namespace ts {
function recompile() {
timerHandle = undefined;
reportDiagnostic(createCompilerDiagnostic(Diagnostics.File_change_detected_Starting_incremental_compilation));
reportWatchDiagnostic(createCompilerDiagnostic(Diagnostics.File_change_detected_Starting_incremental_compilation));
performCompilation();
}
}
@@ -361,7 +379,7 @@ namespace ts {
function compileProgram(): ExitStatus {
let diagnostics: Diagnostic[];
// First get and report any syntactic errors.
diagnostics = program.getSyntacticDiagnostics();
@@ -497,7 +515,7 @@ namespace ts {
function writeConfigFile(options: CompilerOptions, fileNames: string[]) {
let currentDirectory = sys.getCurrentDirectory();
let file = combinePaths(currentDirectory, 'tsconfig.json');
let file = combinePaths(currentDirectory, "tsconfig.json");
if (sys.fileExists(file)) {
reportDiagnostic(createCompilerDiagnostic(Diagnostics.A_tsconfig_json_file_is_already_defined_at_Colon_0, file));
}
@@ -519,8 +537,8 @@ namespace ts {
return;
function serializeCompilerOptions(options: CompilerOptions): Map<string | number | boolean | string[]> {
let result: Map<string | number | boolean | string[]> = {};
function serializeCompilerOptions(options: CompilerOptions): Map<CompilerOptionsValueType> {
let result: Map<CompilerOptionsValueType> = {};
let optionsNameMap = getOptionNameMap().optionNameMap;
for (let name in options) {
+36 -17
View File
@@ -376,6 +376,7 @@ namespace ts {
OctalLiteral = 0x00010000, // Octal numeric literal
Namespace = 0x00020000, // Namespace declaration
ExportContext = 0x00040000, // Export context (initialized by binding)
ContainsThis = 0x00080000, // Interface contains references to "this"
Modifier = Export | Ambient | Public | Private | Protected | Static | Abstract | Default | Async,
AccessibilityModifier = Public | Private | Protected,
@@ -1244,7 +1245,7 @@ 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>;
@@ -1312,12 +1313,12 @@ namespace ts {
}
export interface Program extends ScriptReferenceHost {
/**
* Get a list of root file names that were passed to a 'createProgram'
*/
getRootFileNames(): string[]
getRootFileNames(): string[];
/**
* Get a list of files in the program
*/
@@ -1496,6 +1497,7 @@ namespace ts {
// declaration emitter to help determine if it should patch up the final declaration file
// with import statements it previously saw (but chose not to emit).
trackSymbol(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): void;
reportInaccessibleThisError(): void;
}
export const enum TypeFormatFlags {
@@ -1598,7 +1600,7 @@ namespace ts {
getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number;
getBlockScopedVariableId(node: Identifier): number;
getReferencedValueDeclaration(reference: Identifier): Declaration;
getTypeReferenceSerializationKind(typeName: EntityName): TypeReferenceSerializationKind;
getTypeReferenceSerializationKind(typeName: EntityName): TypeReferenceSerializationKind;
isOptionalParameter(node: ParameterDeclaration): boolean;
}
@@ -1797,6 +1799,7 @@ namespace ts {
/* @internal */
ContainsAnyFunctionType = 0x00800000, // Type is or contains object literal type
ESSymbol = 0x01000000, // Type of symbol primitive introduced in ES6
ThisType = 0x02000000, // This type
/* @internal */
Intrinsic = Any | String | Number | Boolean | ESSymbol | Void | Undefined | Null,
@@ -1842,6 +1845,7 @@ namespace ts {
typeParameters: TypeParameter[]; // Type parameters (undefined if non-generic)
outerTypeParameters: TypeParameter[]; // Outer type parameters (undefined if none)
localTypeParameters: TypeParameter[]; // Local type parameters (undefined if none)
thisType: TypeParameter; // The "this" type (undefined if none)
/* @internal */
resolvedBaseConstructorType?: Type; // Resolved base constructor type of class
/* @internal */
@@ -1856,10 +1860,17 @@ namespace ts {
declaredNumberIndexType: Type; // Declared numeric index type
}
// Type references (TypeFlags.Reference)
// Type references (TypeFlags.Reference). When a class or interface has type parameters or
// a "this" type, references to the class or interface are made using type references. The
// typeArguments property specififes the types to substitute for the type parameters of the
// class or interface and optionally includes an extra element that specifies the type to
// substitute for "this" in the resulting instantiation. When no extra argument is present,
// the type reference itself is substituted for "this". The typeArguments property is undefined
// if the class or interface has no type parameters and the reference isn't specifying an
// explicit "this" argument.
export interface TypeReference extends ObjectType {
target: GenericType; // Type reference target
typeArguments: Type[]; // Type reference type arguments
typeArguments: Type[]; // Type reference type arguments (undefined if none)
}
// Generic class and interface types
@@ -1869,7 +1880,7 @@ namespace ts {
}
export interface TupleType extends ObjectType {
elementTypes: Type[]; // Element types
elementTypes: Type[]; // Element types
}
export interface UnionOrIntersectionType extends Type {
@@ -1884,6 +1895,13 @@ namespace ts {
export interface IntersectionType extends UnionOrIntersectionType { }
/* @internal */
// An instantiated anonymous type has a target and a mapper
export interface AnonymousType extends ObjectType {
target?: AnonymousType; // Instantiation target
mapper?: TypeMapper; // Instantiation mapper
}
/* @internal */
// Resolved object, union, or intersection type
export interface ResolvedType extends ObjectType, UnionOrIntersectionType {
@@ -2014,12 +2032,12 @@ namespace ts {
Error,
Message,
}
export const enum ModuleResolutionKind {
Classic = 1,
NodeJs = 2
}
export interface CompilerOptions {
allowNonTsExtensions?: boolean;
charset?: string;
@@ -2079,6 +2097,7 @@ namespace ts {
AMD = 2,
UMD = 3,
System = 4,
ES6 = 5,
}
export const enum JsxEmit {
@@ -2278,15 +2297,15 @@ 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;
/*
@@ -2297,12 +2316,12 @@ namespace ts {
*/
isExternalLibraryImport?: boolean;
}
export interface ResolvedModuleWithFailedLookupLocations {
resolvedModule: ResolvedModule;
failedLookupLocations: string[];
}
export interface CompilerHost extends ModuleResolutionHost {
getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void): SourceFile;
getCancellationToken?(): CancellationToken;
@@ -2312,7 +2331,7 @@ 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
@@ -2351,7 +2370,7 @@ namespace ts {
// operation caused diagnostics to be returned by storing and comparing the return value
// of this method before/after the operation is performed.
getModificationCount(): number;
/* @internal */ reattachFileDiagnostics(newFile: SourceFile): void;
}
}
+23 -12
View File
@@ -65,7 +65,8 @@ namespace ts {
increaseIndent: () => { },
decreaseIndent: () => { },
clear: () => str = "",
trackSymbol: () => { }
trackSymbol: () => { },
reportInaccessibleThisError: () => { }
};
}
@@ -98,8 +99,8 @@ namespace ts {
}
return true;
}
}
export function hasResolvedModule(sourceFile: SourceFile, moduleNameText: string): boolean {
return sourceFile.resolvedModules && hasProperty(sourceFile.resolvedModules, moduleNameText);
}
@@ -468,13 +469,12 @@ namespace ts {
else if (node.parent.kind === SyntaxKind.PropertyAccessExpression && (<PropertyAccessExpression>node.parent).name === node) {
node = node.parent;
}
// fall through
case SyntaxKind.QualifiedName:
case SyntaxKind.PropertyAccessExpression:
// At this point, node is either a qualified name or an identifier
Debug.assert(node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.QualifiedName || node.kind === SyntaxKind.PropertyAccessExpression,
"'node' was expected to be a qualified name, identifier or property access in 'isTypeNode'.");
case SyntaxKind.QualifiedName:
case SyntaxKind.PropertyAccessExpression:
case SyntaxKind.ThisKeyword:
let parent = node.parent;
if (parent.kind === SyntaxKind.TypeQuery) {
return false;
@@ -621,7 +621,7 @@ namespace ts {
return node && (node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression);
}
export function isFunctionLike(node: Node): boolean {
export function isFunctionLike(node: Node): node is FunctionLikeDeclaration {
if (node) {
switch (node.kind) {
case SyntaxKind.Constructor:
@@ -733,6 +733,9 @@ namespace ts {
case SyntaxKind.Constructor:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
case SyntaxKind.CallSignature:
case SyntaxKind.ConstructSignature:
case SyntaxKind.IndexSignature:
case SyntaxKind.EnumDeclaration:
case SyntaxKind.SourceFile:
return node;
@@ -895,7 +898,6 @@ namespace ts {
export function isExpression(node: Node): boolean {
switch (node.kind) {
case SyntaxKind.ThisKeyword:
case SyntaxKind.SuperKeyword:
case SyntaxKind.NullKeyword:
case SyntaxKind.TrueKeyword:
@@ -928,6 +930,7 @@ namespace ts {
case SyntaxKind.JsxElement:
case SyntaxKind.JsxSelfClosingElement:
case SyntaxKind.YieldExpression:
case SyntaxKind.AwaitExpression:
return true;
case SyntaxKind.QualifiedName:
while (node.parent.kind === SyntaxKind.QualifiedName) {
@@ -941,6 +944,7 @@ namespace ts {
// fall through
case SyntaxKind.NumericLiteral:
case SyntaxKind.StringLiteral:
case SyntaxKind.ThisKeyword:
let parent = node.parent;
switch (parent.kind) {
case SyntaxKind.VariableDeclaration:
@@ -981,6 +985,7 @@ namespace ts {
return node === (<ComputedPropertyName>parent).expression;
case SyntaxKind.Decorator:
case SyntaxKind.JsxExpression:
case SyntaxKind.JsxSpreadAttribute:
return true;
case SyntaxKind.ExpressionWithTypeArguments:
return (<ExpressionWithTypeArguments>parent).expression === node && isExpressionWithTypeArgumentsInClassExtendsClause(parent);
@@ -993,6 +998,12 @@ namespace ts {
return false;
}
export function isExternalModuleNameRelative(moduleName: string): boolean {
// TypeScript 1.0 spec (April 2014): 11.2.1
// An external module name is "relative" if the first term is "." or "..".
return moduleName.substr(0, 2) === "./" || moduleName.substr(0, 3) === "../" || moduleName.substr(0, 2) === ".\\" || moduleName.substr(0, 3) === "..\\";
}
export function isInstantiatedModule(node: ModuleDeclaration, preserveConstEnums: boolean) {
let moduleState = getModuleInstanceState(node);
return moduleState === ModuleInstanceState.Instantiated ||
@@ -1516,12 +1527,12 @@ namespace ts {
function getModificationCount() {
return modificationCount;
}
function reattachFileDiagnostics(newFile: SourceFile): void {
if (!hasProperty(fileDiagnostics, newFile.fileName)) {
return;
}
for (let diagnostic of fileDiagnostics[newFile.fileName]) {
diagnostic.file = newFile;
}
@@ -2068,7 +2079,7 @@ namespace ts {
export function getLocalSymbolForExportDefault(symbol: Symbol) {
return symbol && symbol.valueDeclaration && (symbol.valueDeclaration.flags & NodeFlags.Default) ? symbol.valueDeclaration.localSymbol : undefined;
}
export function hasExtension(fileName: string): boolean {
return getBaseFileName(fileName).indexOf(".") >= 0;
}
+7 -3
View File
@@ -1,6 +1,7 @@
/// <reference path="harness.ts" />
/// <reference path="runnerbase.ts" />
/// <reference path="typeWriter.ts" />
/* tslint:disable:no-null */
const enum CompilerTestType {
Conformance,
@@ -32,7 +33,8 @@ class CompilerBaselineRunner extends RunnerBase {
}
else if (testType === CompilerTestType.Test262) {
this.testSuiteName = "test262";
} else {
}
else {
this.testSuiteName = "compiler"; // default to this for historical reasons
}
this.basePath += "/" + this.testSuiteName;
@@ -82,7 +84,8 @@ class CompilerBaselineRunner extends RunnerBase {
otherFiles.push({ unitName: rootDir + unit.name, content: unit.content });
}
});
} else {
}
else {
toBeCompiled = units.map(unit => {
return { unitName: rootDir + unit.name, content: unit.content };
});
@@ -193,7 +196,8 @@ class CompilerBaselineRunner extends RunnerBase {
if (jsCode.length > 0) {
return tsCode + "\r\n\r\n" + jsCode;
} else {
}
else {
return null;
}
});
+99 -55
View File
@@ -18,8 +18,9 @@
/// <reference path="harnessLanguageService.ts" />
/// <reference path="harness.ts" />
/// <reference path="fourslashRunner.ts" />
/* tslint:disable:no-null */
module FourSlash {
namespace FourSlash {
ts.disableIncrementalParsing = false;
// Represents a parsed source file with metadata
@@ -156,7 +157,7 @@ module FourSlash {
return true;
}
public setCancelled(numberOfCalls: number = 0): void {
public setCancelled(numberOfCalls = 0): void {
ts.Debug.assert(numberOfCalls >= 0);
this.numberOfCallsBeforeCancellation = numberOfCalls;
}
@@ -258,7 +259,8 @@ module FourSlash {
this.inputFiles[file.fileName] = file.content;
if (!startResolveFileRef && file.fileOptions[metadataOptionNames.resolveReference] === "true") {
startResolveFileRef = file;
} else if (startResolveFileRef) {
}
else if (startResolveFileRef) {
// If entry point for resolving file references is already specified, report duplication error
throw new Error("There exists a Fourslash file which has resolveReference flag specified; remove duplicated resolveReference flag");
}
@@ -361,7 +363,8 @@ module FourSlash {
this.currentCaretPosition = Math.min(this.currentCaretPosition, this.getFileContent(this.activeFile.fileName).length);
if (count > 0) {
this.scenarioActions.push(`<MoveCaretRight NumberOfChars="${count}" />`);
} else {
}
else {
this.scenarioActions.push(`<MoveCaretLeft NumberOfChars="${-count}" />`);
}
}
@@ -436,7 +439,8 @@ module FourSlash {
predicate = function (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) {
return ((errorMinChar >= startPos) && (errorLimChar >= startPos)) ? true : false;
};
} else {
}
else {
predicate = function (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) {
return ((errorMinChar <= startPos) && (errorLimChar <= startPos)) ? true : false;
};
@@ -476,7 +480,8 @@ module FourSlash {
private printErrorLog(expectErrors: boolean, errors: ts.Diagnostic[]) {
if (expectErrors) {
Harness.IO.log("Expected error not found. Error list is:");
} else {
}
else {
Harness.IO.log("Unexpected error(s) found. Error list is:");
}
@@ -549,10 +554,12 @@ module FourSlash {
if (negative) {
this.verifyMemberListIsEmpty(false);
return;
} else {
}
else {
this.scenarioActions.push("<ShowCompletionList />");
}
} else {
}
else {
this.scenarioActions.push("<ShowCompletionList />");
this.scenarioActions.push(`<VerifyCompletionItemsCount Count="${expectedCount}" ${(negative ? "ExpectsFailure=\"true\" " : "")}/>`);
}
@@ -595,14 +602,16 @@ module FourSlash {
public verifyMemberListIsEmpty(negative: boolean) {
if (negative) {
this.scenarioActions.push("<ShowCompletionList />");
} else {
}
else {
this.scenarioActions.push("<ShowCompletionList ExpectsFailure=\"true\" />");
}
let members = this.getMemberListAtCaret();
if ((!members || members.entries.length === 0) && negative) {
this.raiseError("Member list is empty at Caret");
} else if ((members && members.entries.length !== 0) && !negative) {
}
else if ((members && members.entries.length !== 0) && !negative) {
let errorMsg = "\n" + "Member List contains: [" + members.entries[0].name;
for (let i = 1; i < members.entries.length; i++) {
@@ -639,7 +648,8 @@ module FourSlash {
if ((completions && !completions.isNewIdentifierLocation) && !negative) {
this.raiseError("Expected builder completion entry");
} else if ((completions && completions.isNewIdentifierLocation) && negative) {
}
else if ((completions && completions.isNewIdentifierLocation) && negative) {
this.raiseError("Un-expected builder completion entry");
}
}
@@ -751,7 +761,7 @@ module FourSlash {
this.raiseError(`verifyReferencesAtPositionListContains failed - could not find the item: ${JSON.stringify(missingItem)} in the returned list: (${JSON.stringify(references)})`);
}
public verifyReferencesCountIs(count: number, localFilesOnly: boolean = true) {
public verifyReferencesCountIs(count: number, localFilesOnly = true) {
this.taoInvalidReason = "verifyReferences NYI";
let references = this.getReferencesAtCaret();
@@ -832,7 +842,8 @@ module FourSlash {
if (expectedDocumentation != undefined) {
assert.notEqual(actualQuickInfoDocumentation, expectedDocumentation, this.messageAtLastKnownMarker("quick info doc comment"));
}
} else {
}
else {
if (expectedText !== undefined) {
assert.equal(actualQuickInfoText, expectedText, this.messageAtLastKnownMarker("quick info text"));
}
@@ -1014,7 +1025,8 @@ module FourSlash {
if (!actual) {
this.raiseError("Expected signature help to be present, but it wasn't");
}
} else {
}
else {
if (actual) {
this.raiseError(`Expected no signature help, but got "${JSON.stringify(actual)}"`);
}
@@ -1371,7 +1383,8 @@ module FourSlash {
public type(text: string) {
if (text === "") {
this.taoInvalidReason = "Test used empty-insert workaround.";
} else {
}
else {
this.scenarioActions.push(`<InsertText><![CDATA[${text}]]></InsertText>`);
}
@@ -1398,7 +1411,8 @@ module FourSlash {
if (ch === "(" || ch === ",") {
/* Signature help*/
this.languageService.getSignatureHelpItems(this.activeFile.fileName, offset);
} else if (prevChar === " " && /A-Za-z_/.test(ch)) {
}
else if (prevChar === " " && /A-Za-z_/.test(ch)) {
/* Completions */
this.languageService.getCompletionsAtPosition(this.activeFile.fileName, offset);
}
@@ -1547,7 +1561,8 @@ module FourSlash {
if (marker.position < limChar) {
// Marker is inside the edit - mark it as invalidated (?)
marker.position = -1;
} else {
}
else {
// Move marker back/forward by the appropriate amount
marker.position += (minChar - limChar) + text.length;
}
@@ -1568,7 +1583,8 @@ module FourSlash {
public goToDefinition(definitionIndex: number) {
if (definitionIndex === 0) {
this.scenarioActions.push("<GoToDefinition />");
} else {
}
else {
this.taoInvalidReason = "GoToDefinition not supported for non-zero definition indices";
}
@@ -1650,7 +1666,8 @@ module FourSlash {
if (negative) {
assert.notEqual(actualDefinitionName, expectedName, this.messageAtLastKnownMarker("Definition Info Name"));
assert.notEqual(actualDefinitionContainerName, expectedContainerName, this.messageAtLastKnownMarker("Definition Info Container Name"));
} else {
}
else {
assert.equal(actualDefinitionName, expectedName, this.messageAtLastKnownMarker("Definition Info Name"));
assert.equal(actualDefinitionContainerName, expectedContainerName, this.messageAtLastKnownMarker("Definition Info Container Name"));
}
@@ -1897,26 +1914,33 @@ module FourSlash {
if (expected === undefined) {
if (actual) {
this.raiseError(name + ' failed - expected no template but got {newText: \"' + actual.newText + '\" caretOffset: ' + actual.caretOffset + '}');
this.raiseError(name + " failed - expected no template but got {newText: \"" + actual.newText + "\" caretOffset: " + actual.caretOffset + "}");
}
return;
}
else {
if (actual === undefined) {
this.raiseError(name + ' failed - expected the template {newText: \"' + actual.newText + '\" caretOffset: ' + actual.caretOffset + '} but got nothing instead');
this.raiseError(name + " failed - expected the template {newText: \"" + actual.newText + "\" caretOffset: " + actual.caretOffset + "} but got nothing instead");
}
if (actual.newText !== expected.newText) {
this.raiseError(name + ' failed - expected insertion:\n' + expected.newText + '\nactual insertion:\n' + actual.newText);
this.raiseError(name + " failed - expected insertion:\n" + this.clarifyNewlines(expected.newText) + "\nactual insertion:\n" + this.clarifyNewlines(actual.newText));
}
if (actual.caretOffset !== expected.caretOffset) {
this.raiseError(name + ' failed - expected caretOffset: ' + expected.caretOffset + ',\nactual caretOffset:' + actual.caretOffset);
this.raiseError(name + " failed - expected caretOffset: " + expected.caretOffset + ",\nactual caretOffset:" + actual.caretOffset);
}
}
}
private clarifyNewlines(str: string) {
return str.replace(/\r?\n/g, lineEnding => {
const representation = lineEnding === "\r\n" ? "CRLF" : "LF";
return "# - " + representation + lineEnding;
});
}
public verifyMatchingBracePosition(bracePosition: number, expectedMatchPosition: number) {
this.taoInvalidReason = "verifyMatchingBracePosition NYI";
@@ -1929,9 +1953,11 @@ module FourSlash {
let actualMatchPosition = -1;
if (bracePosition === actual[0].start) {
actualMatchPosition = actual[1].start;
} else if (bracePosition === actual[1].start) {
}
else if (bracePosition === actual[1].start) {
actualMatchPosition = actual[0].start;
} else {
}
else {
this.raiseError(`verifyMatchingBracePosition failed - could not find the brace position: ${bracePosition} in the returned list: (${actual[0].start},${ts.textSpanEnd(actual[0])}) and (${actual[1].start},${ts.textSpanEnd(actual[1])})`);
}
@@ -2101,7 +2127,7 @@ module FourSlash {
let occurrences = this.getOccurrencesAtCurrentPosition();
if (!occurrences || occurrences.length === 0) {
this.raiseError('verifyOccurrencesAtPositionListContains failed - found 0 references, expected at least one.');
this.raiseError("verifyOccurrencesAtPositionListContains failed - found 0 references, expected at least one.");
}
for (let occurrence of occurrences) {
@@ -2133,12 +2159,12 @@ module FourSlash {
}
public verifyDocumentHighlightsAtPositionListContains(fileName: string, start: number, end: number, fileNamesToSearch: string[], kind?: string) {
this.taoInvalidReason = 'verifyDocumentHighlightsAtPositionListContains NYI';
this.taoInvalidReason = "verifyDocumentHighlightsAtPositionListContains NYI";
let documentHighlights = this.getDocumentHighlightsAtCurrentPosition(fileNamesToSearch);
if (!documentHighlights || documentHighlights.length === 0) {
this.raiseError('verifyDocumentHighlightsAtPositionListContains failed - found 0 highlights, expected at least one.');
this.raiseError("verifyDocumentHighlightsAtPositionListContains failed - found 0 highlights, expected at least one.");
}
for (let documentHighlight of documentHighlights) {
@@ -2161,15 +2187,15 @@ module FourSlash {
}
public verifyDocumentHighlightsAtPositionListCount(expectedCount: number, fileNamesToSearch: string[]) {
this.taoInvalidReason = 'verifyDocumentHighlightsAtPositionListCount NYI';
this.taoInvalidReason = "verifyDocumentHighlightsAtPositionListCount NYI";
let documentHighlights = this.getDocumentHighlightsAtCurrentPosition(fileNamesToSearch);
let actualCount = documentHighlights
? documentHighlights.reduce((currentCount, { highlightSpans }) => currentCount + highlightSpans.length, 0)
let actualCount = documentHighlights
? documentHighlights.reduce((currentCount, { highlightSpans }) => currentCount + highlightSpans.length, 0)
: 0;
if (expectedCount !== actualCount) {
this.raiseError('verifyDocumentHighlightsAtPositionListCount failed - actual: ' + actualCount + ', expected:' + expectedCount);
this.raiseError("verifyDocumentHighlightsAtPositionListCount failed - actual: " + actualCount + ", expected:" + expectedCount);
}
}
@@ -2243,10 +2269,12 @@ module FourSlash {
let index = <number>indexOrName;
if (index >= this.testData.files.length) {
throw new Error(`File index (${index}) in openFile was out of range. There are only ${this.testData.files.length} files in this test.`);
} else {
}
else {
result = this.testData.files[index];
}
} else if (typeof indexOrName === "string") {
}
else if (typeof indexOrName === "string") {
let name = <string>indexOrName;
// names are stored in the compiler with this relative path, this allows people to use goTo.file on just the fileName
@@ -2269,7 +2297,8 @@ module FourSlash {
if (!foundIt) {
throw new Error(`No test file named "${name}" exists. Available file names are: ${availableNames.join(", ")}`);
}
} else {
}
else {
throw new Error("Unknown argument type");
}
@@ -2287,7 +2316,8 @@ module FourSlash {
let markerNames: string[] = [];
for (let m in this.testData.markerPositions) markerNames.push(m);
throw new Error(`Unknown marker "${markerName}" Available markers: ${markerNames.map(m => "\"" + m + "\"").join(", ")}`);
} else {
}
else {
return markerPos;
}
}
@@ -2432,13 +2462,15 @@ module FourSlash {
// Append to the current subfile content, inserting a newline needed
if (currentFileContent === null) {
currentFileContent = "";
} else {
}
else {
// End-of-line
currentFileContent = currentFileContent + "\n";
}
currentFileContent = currentFileContent + line.substr(4);
} else if (line.substr(0, 2) === "//") {
}
else if (line.substr(0, 2) === "//") {
// Comment line, check for global/file @options and record them
let match = optionRegex.exec(line.substr(2));
if (match) {
@@ -2468,17 +2500,20 @@ module FourSlash {
currentFileName = basePath + "/" + match[2];
currentFileOptions[match[1]] = match[2];
} else {
}
else {
// Add other fileMetadata flag
currentFileOptions[match[1]] = match[2];
}
}
}
// TODO: should be '==='?
} else if (line == "" || lineLength === 0) {
}
else if (line == "" || lineLength === 0) {
// Previously blank lines between fourslash content caused it to be considered as 2 files,
// Remove this behavior since it just causes errors now
} else {
}
else {
// Empty line or code line, terminate current subfile if there is one
if (currentFileContent) {
let file = parseFileContent(currentFileContent, currentFileName, markerPositions, markers, ranges);
@@ -2548,7 +2583,8 @@ module FourSlash {
try {
// Attempt to parse the marker value as JSON
markerValue = JSON.parse("{ " + text + " }");
} catch (e) {
}
catch (e) {
reportError(fileName, location.sourceLine, location.sourceColumn, "Unable to parse marker text " + e.message);
}
@@ -2584,7 +2620,8 @@ module FourSlash {
let message = "Marker '" + name + "' is duplicated in the source file contents.";
reportError(marker.fileName, location.sourceLine, location.sourceColumn, message);
return null;
} else {
}
else {
markerMap[name] = marker;
markers.push(marker);
return marker;
@@ -2598,7 +2635,7 @@ module FourSlash {
let validMarkerChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz$1234567890_";
/// The file content (minus metacharacters) so far
let output: string = "";
let output = "";
/// The current marker (or maybe multi-line comment?) we're parsing, possibly
let openMarker: ILocationInformation = null;
@@ -2610,22 +2647,23 @@ module FourSlash {
let localRanges: Range[] = [];
/// The latest position of the start of an unflushed plain text area
let lastNormalCharPosition: number = 0;
let lastNormalCharPosition = 0;
/// The total number of metacharacters removed from the file (so far)
let difference: number = 0;
let difference = 0;
/// The fourslash file state object we are generating
let state: State = State.none;
/// Current position data
let line: number = 1;
let column: number = 1;
let line = 1;
let column = 1;
let flush = (lastSafeCharIndex: number) => {
if (lastSafeCharIndex === undefined) {
output = output + content.substr(lastNormalCharPosition);
} else {
}
else {
output = output + content.substr(lastNormalCharPosition, lastSafeCharIndex - lastNormalCharPosition);
}
};
@@ -2648,7 +2686,8 @@ module FourSlash {
flush(i - 1);
lastNormalCharPosition = i + 1;
difference += 2;
} else if (previousChar === "|" && currentChar === "]") {
}
else if (previousChar === "|" && currentChar === "]") {
// found a range end
let rangeStart = openRanges.pop();
if (!rangeStart) {
@@ -2667,7 +2706,8 @@ module FourSlash {
flush(i - 1);
lastNormalCharPosition = i + 1;
difference += 2;
} else if (previousChar === "/" && currentChar === "*") {
}
else if (previousChar === "/" && currentChar === "*") {
// found a possible marker start
state = State.inSlashStarMarker;
openMarker = {
@@ -2676,7 +2716,8 @@ module FourSlash {
sourceLine: line,
sourceColumn: column,
};
} else if (previousChar === "{" && currentChar === "|") {
}
else if (previousChar === "{" && currentChar === "|") {
// found an object marker start
state = State.inObjectMarker;
openMarker = {
@@ -2729,10 +2770,12 @@ module FourSlash {
// Reset the state
openMarker = null;
state = State.none;
} else if (validMarkerChars.indexOf(currentChar) < 0) {
}
else if (validMarkerChars.indexOf(currentChar) < 0) {
if (currentChar === "*" && i < content.length - 1 && content.charAt(i + 1) === "/") {
// The marker is about to be closed, ignore the 'invalid' char
} else {
}
else {
// We've hit a non-valid marker character, so we were actually in a block comment
// Bail out the text we've gathered so far back into the output
flush(i);
@@ -2748,7 +2791,8 @@ module FourSlash {
if (currentChar === "\n" && previousChar === "\r") {
// Ignore trailing \n after a \r
continue;
} else if (currentChar === "\n" || currentChar === "\r") {
}
else if (currentChar === "\n" || currentChar === "\r") {
line++;
column = 1;
continue;
+5 -3
View File
@@ -1,6 +1,7 @@
///<reference path="fourslash.ts" />
///<reference path="harness.ts"/>
///<reference path="runnerbase.ts" />
/* tslint:disable:no-null */
const enum FourSlashTestType {
Native,
@@ -25,8 +26,8 @@ class FourSlashRunner extends RunnerBase {
this.testSuiteName = "fourslash-shims";
break;
case FourSlashTestType.ShimsWithPreprocess:
this.basePath = 'tests/cases/fourslash/shims-pp';
this.testSuiteName = 'fourslash-shims-pp';
this.basePath = "tests/cases/fourslash/shims-pp";
this.testSuiteName = "fourslash-shims-pp";
break;
case FourSlashTestType.Server:
this.basePath = "tests/cases/fourslash/server";
@@ -87,7 +88,8 @@ class FourSlashRunner extends RunnerBase {
FourSlash.xmlData.forEach(xml => {
if (xml.invalidReason !== null) {
lines.push("<!-- Skipped " + xml.originalName + ", reason: " + xml.invalidReason + " -->");
} else {
}
else {
lines.push(" <Scenario Name=\"" + xml.originalName + "\">");
xml.actions.forEach(action => {
lines.push(" " + action);
+63 -46
View File
@@ -23,6 +23,7 @@
/// <reference path="external\chai.d.ts"/>
/// <reference path="sourceMapRecorder.ts"/>
/// <reference path="runnerbase.ts"/>
/* tslint:disable:no-null */
// Block scoped definitions work poorly for global variables, temporarily enable var
/* tslint:disable:no-var-keyword */
@@ -35,7 +36,7 @@ declare var __dirname: string; // Node-specific
var global = <any>Function("return this").call(null);
/* tslint:enable:no-var-keyword */
module Utils {
namespace Utils {
// Setup some globals based on the current environment
export const enum ExecutionEnvironment {
Node,
@@ -54,17 +55,17 @@ module Utils {
return ExecutionEnvironment.Node;
}
}
export let currentExecutionEnvironment = getExecutionEnvironment();
const Buffer: BufferConstructor = currentExecutionEnvironment !== ExecutionEnvironment.Browser
? require("buffer").Buffer
const Buffer: BufferConstructor = currentExecutionEnvironment !== ExecutionEnvironment.Browser
? require("buffer").Buffer
: undefined;
export function encodeString(s: string): string {
return Buffer ? (new Buffer(s)).toString("utf8") : s;
}
export function evalFile(fileContents: string, fileName: string, nodeContext?: any) {
let environment = getExecutionEnvironment();
switch (environment) {
@@ -76,7 +77,8 @@ module Utils {
let vm = require("vm");
if (nodeContext) {
vm.runInNewContext(fileContents, nodeContext, fileName);
} else {
}
else {
vm.runInThisContext(fileContents, fileName);
}
break;
@@ -126,7 +128,8 @@ module Utils {
let cachedResult = cache[key];
if (cachedResult) {
return cachedResult;
} else {
}
else {
return cache[key] = f.apply(this, arguments);
}
});
@@ -398,7 +401,7 @@ module Utils {
}
}
module Harness.Path {
namespace Harness.Path {
export function getFileName(fullPath: string) {
return fullPath.replace(/^.*[\\\/]/, "");
}
@@ -411,7 +414,7 @@ module Harness.Path {
}
}
module Harness {
namespace Harness {
export interface IO {
newLine(): string;
getCurrentDirectory(): string;
@@ -433,11 +436,11 @@ module Harness {
readDirectory(path: string, extension?: string, exclude?: string[]): string[];
}
export var IO: IO;
// harness always uses one kind of new line
const harnessNewLine = "\r\n";
module IOImpl {
namespace IOImpl {
declare class Enumerator {
public atEnd(): boolean;
public moveNext(): boolean;
@@ -445,14 +448,15 @@ module Harness {
constructor(o: any);
}
export module CScript {
export namespace CScript {
let fso: any;
if (global.ActiveXObject) {
fso = new global.ActiveXObject("Scripting.FileSystemObject");
} else {
}
else {
fso = {};
}
export const args = () => ts.sys.args;
export const getExecutingFilePath = () => ts.sys.getExecutingFilePath();
export const exit = (exitCode: number) => ts.sys.exit(exitCode);
@@ -513,16 +517,17 @@ module Harness {
};
}
export module Node {
export namespace Node {
declare let require: any;
let fs: any, pathModule: any;
if (require) {
fs = require("fs");
pathModule = require("path");
} else {
}
else {
fs = pathModule = {};
}
export const resolvePath = (path: string) => ts.sys.resolvePath(path);
export const getCurrentDirectory = () => ts.sys.getCurrentDirectory();
export const newLine = () => harnessNewLine;
@@ -547,7 +552,8 @@ module Harness {
export function deleteFile(path: string) {
try {
fs.unlinkSync(path);
} catch (e) {
}
catch (e) {
}
}
@@ -561,7 +567,8 @@ module Harness {
// Node will just continue to repeat the root path, rather than return null
if (dirPath === path) {
dirPath = null;
} else {
}
else {
return dirPath;
}
}
@@ -598,7 +605,7 @@ module Harness {
};
}
export module Network {
export namespace Network {
let serverRoot = "http://localhost:8888/";
export const newLine = () => harnessNewLine;
@@ -607,10 +614,11 @@ module Harness {
export const args = () => <string[]>[];
export const getExecutingFilePath = () => "";
export const exit = (exitCode: number) => {};
let supportsCodePage = () => false;
module Http {
let supportsCodePage = () => false;
export let log = (s: string) => console.log(s);
namespace Http {
function waitForXHR(xhr: XMLHttpRequest) {
while (xhr.readyState !== 4) { }
return { status: xhr.status, responseText: xhr.responseText };
@@ -685,10 +693,12 @@ module Harness {
if (dirPath.match(/localhost:\d+$/) || dirPath.match(/localhost:\d+\/$/)) {
dirPath = null;
// path + fileName
} else if (dirPath.indexOf(".") === -1) {
}
else if (dirPath.indexOf(".") === -1) {
dirPath = dirPath.substring(0, dirPath.lastIndexOf("/"));
// path
} else {
}
else {
// strip any trailing slash
if (dirPath.match(/.*\/$/)) {
dirPath = dirPath.substring(0, dirPath.length - 2);
@@ -712,7 +722,8 @@ module Harness {
let results = response.responseText.split(",");
if (spec) {
return results.filter(file => spec.test(file));
} else {
}
else {
return results;
}
}
@@ -722,13 +733,12 @@ module Harness {
};
export let listFiles = Utils.memoize(_listFilesImpl);
export let log = (s: string) => console.log(s);
export function readFile(file: string) {
let response = Http.getFileFromServerSync(serverRoot + file);
if (response.status === 200) {
return response.responseText;
} else {
}
else {
return null;
}
}
@@ -756,7 +766,7 @@ module Harness {
}
}
module Harness {
namespace Harness {
let tcServicesFileName = "typescriptServices.js";
export let libFolder: string;
@@ -787,7 +797,7 @@ module Harness {
export let lightMode = false;
/** Functionality for compiling TypeScript code */
export module Compiler {
export namespace Compiler {
/** Aggregate various writes into a single array of lines. Useful for passing to the
* TypeScript compiler to fill with source code or errors.
*/
@@ -866,7 +876,7 @@ module Harness {
languageVersion: ts.ScriptTarget) {
// We'll only assert inletiants outside of light mode.
const shouldAssertInvariants = !Harness.lightMode;
// Only set the parent nodes if we're asserting inletiants. We don't need them otherwise.
let result = ts.createSourceFile(fileName, sourceText, languageVersion, /*setParentNodes:*/ shouldAssertInvariants);
@@ -1098,7 +1108,7 @@ module Harness {
}
let useCaseSensitiveFileNames = options.useCaseSensitiveFileNames !== undefined ? options.useCaseSensitiveFileNames : Harness.IO.useCaseSensitiveFileNames();
let fileOutputs: GeneratedFile[] = [];
let programFiles = inputFiles.concat(includeBuiltFiles).map(file => file.unitName);
@@ -1227,12 +1237,12 @@ module Harness {
.filter(s => s.length > 0)
.map(s => "!!! " + ts.DiagnosticCategory[error.category].toLowerCase() + " TS" + error.code + ": " + s);
errLines.forEach(e => outputLines.push(e));
// do not count errors from lib.d.ts here, they are computed separately as numLibraryDiagnostics
// if lib.d.ts is explicitly included in input files and there are some errors in it (i.e. because of duplicate identifiers)
// then they will be added twice thus triggering 'total errors' assertion with condition
// 'totalErrorsReportedInNonLibraryFiles + numLibraryDiagnostics + numTest262HarnessDiagnostics, diagnostics.length
if (!error.file || !isLibraryFile(error.file.fileName)) {
totalErrorsReportedInNonLibraryFiles++;
}
@@ -1276,7 +1286,8 @@ module Harness {
// On the last line of the file, fake the next line start number so that we handle errors on the last character of the file correctly
if (lineIndex === lines.length - 1) {
nextLineStart = inputFile.content.length;
} else {
}
else {
nextLineStart = lineStarts[lineIndex + 1];
}
// Emit this line from the original file
@@ -1340,7 +1351,7 @@ module Harness {
// FileName header + content
result += "/*====== " + outputFile.fileName + " ======*/\r\n";
result += outputFile.code;
}
@@ -1440,7 +1451,7 @@ module Harness {
}
}
export module TestCaseParser {
export namespace TestCaseParser {
/** all the necessary information to set the right compiler settings */
export interface CompilerSettings {
[name: string]: string;
@@ -1493,7 +1504,8 @@ module Harness {
let metaDataName = testMetaData[1].toLowerCase();
if (metaDataName === "filename") {
currentFileOptions[testMetaData[1]] = testMetaData[2];
} else {
}
else {
continue;
}
@@ -1514,16 +1526,19 @@ module Harness {
currentFileOptions = {};
currentFileName = testMetaData[2];
refs = [];
} else {
}
else {
// First metadata marker in the file
currentFileName = testMetaData[2];
}
} else {
}
else {
// Subfile content line
// Append to the current subfile content, inserting a newline needed
if (currentFileContent === null) {
currentFileContent = "";
} else {
}
else {
// End-of-line
currentFileContent = currentFileContent + "\n";
}
@@ -1549,7 +1564,7 @@ module Harness {
}
/** Support class for baseline files */
export module Baseline {
export namespace Baseline {
export interface BaselineOptions {
Subfolder?: string;
@@ -1577,7 +1592,8 @@ module Harness {
function baselinePath(fileName: string, type: string, baselineFolder: string, subfolder?: string) {
if (subfolder !== undefined) {
return Harness.userSpecifiedRoot + baselineFolder + "/" + subfolder + "/" + type + "/" + fileName;
} else {
}
else {
return Harness.userSpecifiedRoot + baselineFolder + "/" + type + "/" + fileName;
}
}
@@ -1669,7 +1685,8 @@ module Harness {
actual = generateActual(actualFileName, generateContent);
let comparison = compareToBaseline(actual, relativeFileName, opts);
writeComparison(comparison.expected, comparison.actual, relativeFileName, actualFileName, descriptionForDescribe);
} else {
}
else {
actual = generateActual(actualFileName, generateContent);
let comparison = compareToBaseline(actual, relativeFileName, opts);
+35 -35
View File
@@ -3,11 +3,11 @@
/// <reference path="..\server\client.ts" />
/// <reference path="harness.ts" />
module Harness.LanguageService {
namespace Harness.LanguageService {
export class ScriptInfo {
public version: number = 1;
public editRanges: { length: number; textChangeRange: ts.TextChangeRange; }[] = [];
public lineMap: number[] = null;
public lineMap: number[] = undefined;
constructor(public fileName: string, public content: string) {
this.setContent(content);
@@ -95,8 +95,8 @@ module Harness.LanguageService {
let oldShim = <ScriptSnapshotProxy>oldScript;
let range = this.scriptSnapshot.getChangeRange(oldShim.scriptSnapshot);
if (range === null) {
return null;
if (range === undefined) {
return undefined;
}
return JSON.stringify({ span: { start: range.span.start, length: range.span.length }, newLength: range.newLength });
@@ -118,11 +118,11 @@ module Harness.LanguageService {
getPreProcessedFileInfo(fileName: string, fileContents: string): ts.PreProcessedFileInfo;
}
export class LanguageServiceAdapterHost {
export class LanguageServiceAdapterHost {
protected fileNameToScript: ts.Map<ScriptInfo> = {};
constructor(protected cancellationToken = DefaultHostCancellationToken.Instance,
protected settings = ts.getDefaultCompilerOptions()) {
protected settings = ts.getDefaultCompilerOptions()) {
}
public getNewLine(): string {
@@ -145,7 +145,7 @@ module Harness.LanguageService {
public editScript(fileName: string, start: number, end: number, newText: string) {
let script = this.getScriptInfo(fileName);
if (script !== null) {
if (script !== undefined) {
script.editContent(start, end, newText);
return;
}
@@ -169,7 +169,7 @@ module Harness.LanguageService {
}
/// Native adapter
class NativeLanguageServiceHost extends LanguageServiceAdapterHost implements ts.LanguageServiceHost {
class NativeLanguageServiceHost extends LanguageServiceAdapterHost implements ts.LanguageServiceHost {
getCompilationSettings() { return this.settings; }
getCancellationToken() { return this.cancellationToken; }
getCurrentDirectory(): string { return ""; }
@@ -191,7 +191,7 @@ module Harness.LanguageService {
export class NativeLanugageServiceAdapter implements LanguageServiceAdapter {
private host: NativeLanguageServiceHost;
constructor(cancellationToken?: ts.HostCancellationToken, options?: ts.CompilerOptions) {
constructor(cancellationToken?: ts.HostCancellationToken, options?: ts.CompilerOptions) {
this.host = new NativeLanguageServiceHost(cancellationToken, options);
}
getHost() { return this.host; }
@@ -204,14 +204,14 @@ module Harness.LanguageService {
class ShimLanguageServiceHost extends LanguageServiceAdapterHost implements ts.LanguageServiceShimHost, ts.CoreServicesShimHost {
private nativeHost: NativeLanguageServiceHost;
public getModuleResolutionsForFile: (fileName: string)=> string;
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 compilerOptions = this.nativeHost.getCompilationSettings();
let moduleResolutionHost: ts.ModuleResolutionHost = {
fileExists: fileName => this.getScriptInfo(fileName) !== undefined,
readFile: fileName => {
@@ -230,7 +230,7 @@ module Harness.LanguageService {
}
}
return JSON.stringify(imports);
}
};
}
}
@@ -247,7 +247,7 @@ module Harness.LanguageService {
getScriptFileNames(): string { return JSON.stringify(this.nativeHost.getScriptFileNames()); }
getScriptSnapshot(fileName: string): ts.ScriptSnapshotShim {
let nativeScriptSnapshot = this.nativeHost.getScriptSnapshot(fileName);
return nativeScriptSnapshot && new ScriptSnapshotProxy(nativeScriptSnapshot);
return nativeScriptSnapshot && new ScriptSnapshotProxy(nativeScriptSnapshot);
}
getScriptVersion(fileName: string): string { return this.nativeHost.getScriptVersion(fileName); }
getLocalizedDiagnosticMessages(): string { return JSON.stringify({}); }
@@ -255,17 +255,17 @@ module Harness.LanguageService {
readDirectory(rootDir: string, extension: string): string {
throw new Error("NYI");
}
fileExists(fileName: string) { return this.getScriptInfo(fileName) !== undefined; }
readFile(fileName: string) {
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); }
}
class ClassifierShimProxy implements ts.Classifier {
class ClassifierShimProxy implements ts.Classifier {
constructor(private shim: ts.ClassifierShim) {
}
getEncodedLexicalClassifications(text: string, lexState: ts.EndOfLineState, classifyKeywordsInGenerics?: boolean): ts.Classifications {
@@ -302,7 +302,7 @@ module Harness.LanguageService {
if (parsedResult.error) {
throw new Error("Language Service Shim Error: " + JSON.stringify(parsedResult.error));
}
else if (parsedResult.canceled) {
else if (parsedResult.canceled) {
throw new ts.OperationCanceledException();
}
return parsedResult.result;
@@ -369,7 +369,7 @@ module Harness.LanguageService {
getDefinitionAtPosition(fileName: string, position: number): ts.DefinitionInfo[] {
return unwrapJSONCallResult(this.shim.getDefinitionAtPosition(fileName, position));
}
getTypeDefinitionAtPosition(fileName: string, position: number): ts.DefinitionInfo[]{
getTypeDefinitionAtPosition(fileName: string, position: number): ts.DefinitionInfo[] {
return unwrapJSONCallResult(this.shim.getTypeDefinitionAtPosition(fileName, position));
}
getReferencesAtPosition(fileName: string, position: number): ts.ReferenceEntry[] {
@@ -474,19 +474,19 @@ module Harness.LanguageService {
}
// Server adapter
class SessionClientHost extends NativeLanguageServiceHost implements ts.server.SessionClientHost {
class SessionClientHost extends NativeLanguageServiceHost implements ts.server.SessionClientHost {
private client: ts.server.SessionClient;
constructor(cancellationToken: ts.HostCancellationToken, settings: ts.CompilerOptions) {
super(cancellationToken, settings);
}
onMessage(message: string): void {
onMessage(message: string): void {
}
writeMessage(message: string): void {
writeMessage(message: string): void {
}
setClient(client: ts.server.SessionClient) {
@@ -504,7 +504,7 @@ module Harness.LanguageService {
}
}
class SessionServerHost implements ts.server.ServerHost, ts.server.Logger {
class SessionServerHost implements ts.server.ServerHost, ts.server.Logger {
args: string[] = [];
newLine: string;
useCaseSensitiveFileNames: boolean = false;
@@ -513,23 +513,23 @@ module Harness.LanguageService {
this.newLine = this.host.getNewLine();
}
onMessage(message: string): void {
onMessage(message: string): void {
}
writeMessage(message: string): void {
}
write(message: string): void {
write(message: string): void {
this.writeMessage(message);
}
readFile(fileName: string): string {
if (fileName.indexOf(Harness.Compiler.defaultLibFileName) >= 0) {
if (fileName.indexOf(Harness.Compiler.defaultLibFileName) >= 0) {
fileName = Harness.Compiler.defaultLibFileName;
}
let snapshot = this.host.getScriptSnapshot(fileName);
return snapshot && snapshot.getText(0, snapshot.getLength());
}
@@ -567,8 +567,8 @@ module Harness.LanguageService {
readDirectory(path: string, extension?: string): string[] {
throw new Error("Not implemented Yet.");
}
watchFile(fileName: string, callback: (fileName: string) => void): ts.FileWatcher {
watchFile(fileName: string, callback: (fileName: string) => void): ts.FileWatcher {
return { close() { } };
}
@@ -582,7 +582,7 @@ module Harness.LanguageService {
msg(message: string) {
return this.host.log(message);
}
loggingEnabled() {
return true;
}
@@ -602,7 +602,7 @@ module Harness.LanguageService {
startGroup(): void {
}
}
export class ServerLanugageServiceAdapter implements LanguageServiceAdapter {
private host: SessionClientHost;
private client: ts.server.SessionClient;
+3 -2
View File
@@ -1,6 +1,7 @@
/// <reference path="..\..\src\compiler\sys.ts" />
/// <reference path="..\..\src\harness\harness.ts" />
/// <reference path="..\..\src\harness\runnerbase.ts" />
/* tslint:disable:no-null */
interface FileInformation {
contents: string;
@@ -76,7 +77,7 @@ interface PlaybackControl {
endRecord(): void;
}
module Playback {
namespace Playback {
let recordLog: IOLog = undefined;
let replayLog: IOLog = undefined;
let recordLogFileNameBase = "";
@@ -95,7 +96,7 @@ module Playback {
run.reset = () => {
lookup = null;
};
return run;
}
+11 -8
View File
@@ -1,5 +1,6 @@
///<reference path="harness.ts" />
///<reference path="runnerbase.ts" />
/* tslint:disable:no-null */
// Test case is json of below type in tests/cases/project/
interface ProjectRunnerTestCase extends ts.CompilerOptions{
@@ -26,7 +27,7 @@ interface BatchCompileProjectTestCaseEmittedFile extends Harness.Compiler.Genera
interface CompileProjectFilesResult {
moduleKind: ts.ModuleKind;
program?: ts.Program;
compilerOptions?: ts.CompilerOptions,
compilerOptions?: ts.CompilerOptions;
errors: ts.Diagnostic[];
sourceMapData?: ts.SourceMapData[];
}
@@ -177,16 +178,18 @@ class ProjectRunner extends RunnerBase {
}
}
function batchCompilerProjectTestCase(moduleKind: ts.ModuleKind): BatchCompileProjectTestCaseResult{
function batchCompilerProjectTestCase(moduleKind: ts.ModuleKind): BatchCompileProjectTestCaseResult {
let nonSubfolderDiskFiles = 0;
let outputFiles: BatchCompileProjectTestCaseEmittedFile[] = [];
let inputFiles = testCase.inputFiles;
let { errors, compilerOptions } = createCompilerOptions();
if (errors.length) {
moduleKind,
errors
};
return {
moduleKind,
errors
};
}
let configFileName: string;
if (compilerOptions.project) {
@@ -255,7 +258,7 @@ class ProjectRunner extends RunnerBase {
return { errors, compilerOptions };
}
function getFileNameInTheProjectTest(fileName: string): string {
return ts.isRootedDiskPath(fileName)
? fileName
@@ -363,7 +366,7 @@ class ProjectRunner extends RunnerBase {
allInputFiles.unshift(findOutpuDtsFile(outputDtsFileName));
}
else {
let outputDtsFileName = ts.removeFileExtension(compilerOptions.outFile|| compilerOptions.out) + ".d.ts";
let outputDtsFileName = ts.removeFileExtension(compilerOptions.outFile || compilerOptions.out) + ".d.ts";
let outputDtsFile = findOutpuDtsFile(outputDtsFileName);
if (!ts.contains(allInputFiles, outputDtsFile)) {
allInputFiles.unshift(outputDtsFile);
@@ -393,7 +396,7 @@ class ProjectRunner extends RunnerBase {
sourceFile => sourceFile.fileName !== "lib.d.ts"),
sourceFile => {
return { unitName: sourceFile.fileName, content: sourceFile.text };
}): [];
}) : [];
return Harness.Compiler.getErrorBaseline(inputFiles, compilerResult.errors);
}
+5 -3
View File
@@ -20,8 +20,10 @@
/// <reference path="rwcRunner.ts" />
/// <reference path="harness.ts" />
/* tslint:disable:no-null */
let runners: RunnerBase[] = [];
let iterations: number = 1;
let iterations = 1;
function runTests(runners: RunnerBase[]) {
for (let i = iterations; i > 0; i--) {
@@ -68,10 +70,10 @@ if (testConfigFile !== "") {
case "fourslash-shims":
runners.push(new FourSlashRunner(FourSlashTestType.Shims));
break;
case 'fourslash-shims-pp':
case "fourslash-shims-pp":
runners.push(new FourSlashRunner(FourSlashTestType.ShimsWithPreprocess));
break;
case 'fourslash-server':
case "fourslash-server":
runners.push(new FourSlashRunner(FourSlashTestType.Server));
break;
case "fourslash-generated":
+2 -2
View File
@@ -25,12 +25,12 @@ abstract class RunnerBase {
let fixedPath = path;
// full paths either start with a drive letter or / for *nix, shouldn't have \ in the path at this point
let fullPath = /(\w+:|\/)?([\w+\-\.]|\/)*\.tsx?/g;
let fullPath = /(\w+:|\/)?([\w+\-\.]|\/)*\.tsx?/g;
let fullPathList = fixedPath.match(fullPath);
if (fullPathList) {
fullPathList.forEach((match: string) => fixedPath = fixedPath.replace(match, Harness.Path.getFileName(match)));
}
// when running in the browser the 'full path' is the host name, shows up in error baselines
let localHost = /http:\/localhost:\d+/g;
fixedPath = fixedPath.replace(localHost, "");
+3 -2
View File
@@ -2,8 +2,9 @@
/// <reference path="runnerbase.ts" />
/// <reference path="loggedIO.ts" />
/// <reference path="..\compiler\commandLineParser.ts"/>
/* tslint:disable:no-null */
module RWC {
namespace RWC {
function runWithIOLog(ioLog: IOLog, fn: (oldIO: Harness.IO) => void) {
let oldIO = Harness.IO;
@@ -105,7 +106,7 @@ module RWC {
}
otherFiles.push(getHarnessCompilerInputUnit(fileRead.path));
}
else if (!opts.options.noLib && Harness.isLibraryFile(fileRead.path)){
else if (!opts.options.noLib && Harness.isLibraryFile(fileRead.path)) {
if (!inInputList) {
// If useCustomLibraryFile is true, we will use lib.d.ts from json object
// otherwise use the lib.d.ts from built/local
+4 -4
View File
@@ -15,14 +15,14 @@
///<reference path="harness.ts"/>
module Harness.SourceMapRecoder {
namespace Harness.SourceMapRecoder {
interface SourceMapSpanWithDecodeErrors {
sourceMapSpan: ts.SourceMapSpan;
decodeErrors: string[];
}
module SourceMapDecoder {
namespace SourceMapDecoder {
let sourceMapMappings: string;
let sourceMapNames: string[];
let decodingIndex: number;
@@ -202,7 +202,7 @@ module Harness.SourceMapRecoder {
}
}
module SourceMapSpanWriter {
namespace SourceMapSpanWriter {
let sourceMapRecoder: Compiler.WriterAggregator;
let sourceMapSources: string[];
let sourceMapNames: string[];
@@ -442,7 +442,7 @@ module Harness.SourceMapRecoder {
for (let i = 0; i < sourceMapDataList.length; i++) {
let sourceMapData = sourceMapDataList[i];
let prevSourceFile: ts.SourceFile = null;
let prevSourceFile: ts.SourceFile;
SourceMapSpanWriter.intializeSourceMapSpanWriter(sourceMapRecoder, sourceMapData, jsFiles[i]);
for (let j = 0; j < sourceMapData.sourceMapDecodedMappings.length; j++) {
+1
View File
@@ -1,5 +1,6 @@
/// <reference path="harness.ts" />
/// <reference path="runnerbase.ts" />
/* tslint:disable:no-null */
class Test262BaselineRunner extends RunnerBase {
private static basePath = "internal/cases/test262";
+18 -18
View File
@@ -202,8 +202,8 @@ interface AnalyserNode extends AudioNode {
smoothingTimeConstant: number;
getByteFrequencyData(array: Uint8Array): void;
getByteTimeDomainData(array: Uint8Array): void;
getFloatFrequencyData(array: any): void;
getFloatTimeDomainData(array: any): void;
getFloatFrequencyData(array: Float32Array): void;
getFloatTimeDomainData(array: Float32Array): void;
}
declare var AnalyserNode: {
@@ -290,7 +290,7 @@ interface AudioBuffer {
length: number;
numberOfChannels: number;
sampleRate: number;
getChannelData(channel: number): any;
getChannelData(channel: number): Float32Array;
}
declare var AudioBuffer: {
@@ -334,7 +334,7 @@ interface AudioContext extends EventTarget {
createMediaElementSource(mediaElement: HTMLMediaElement): MediaElementAudioSourceNode;
createOscillator(): OscillatorNode;
createPanner(): PannerNode;
createPeriodicWave(real: any, imag: any): PeriodicWave;
createPeriodicWave(real: Float32Array, imag: Float32Array): PeriodicWave;
createScriptProcessor(bufferSize?: number, numberOfInputChannels?: number, numberOfOutputChannels?: number): ScriptProcessorNode;
createStereoPanner(): StereoPannerNode;
createWaveShaper(): WaveShaperNode;
@@ -392,7 +392,7 @@ interface AudioParam {
linearRampToValueAtTime(value: number, endTime: number): void;
setTargetAtTime(target: number, startTime: number, timeConstant: number): void;
setValueAtTime(value: number, startTime: number): void;
setValueCurveAtTime(values: any, startTime: number, duration: number): void;
setValueCurveAtTime(values: Float32Array, startTime: number, duration: number): void;
}
declare var AudioParam: {
@@ -468,7 +468,7 @@ interface BiquadFilterNode extends AudioNode {
frequency: AudioParam;
gain: AudioParam;
type: string;
getFrequencyResponse(frequencyHz: any, magResponse: any, phaseResponse: any): void;
getFrequencyResponse(frequencyHz: Float32Array, magResponse: Float32Array, phaseResponse: Float32Array): void;
}
declare var BiquadFilterNode: {
@@ -10893,7 +10893,7 @@ declare var WEBGL_depth_texture: {
}
interface WaveShaperNode extends AudioNode {
curve: any;
curve: Float32Array;
oversample: string;
}
@@ -11080,34 +11080,34 @@ interface WebGLRenderingContext {
texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, format: number, type: number, video: HTMLVideoElement): void;
texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, format: number, type: number, pixels: ImageData): void;
uniform1f(location: WebGLUniformLocation, x: number): void;
uniform1fv(location: WebGLUniformLocation, v: any): void;
uniform1fv(location: WebGLUniformLocation, v: Float32Array): void;
uniform1i(location: WebGLUniformLocation, x: number): void;
uniform1iv(location: WebGLUniformLocation, v: Int32Array): void;
uniform2f(location: WebGLUniformLocation, x: number, y: number): void;
uniform2fv(location: WebGLUniformLocation, v: any): void;
uniform2fv(location: WebGLUniformLocation, v: Float32Array): void;
uniform2i(location: WebGLUniformLocation, x: number, y: number): void;
uniform2iv(location: WebGLUniformLocation, v: Int32Array): void;
uniform3f(location: WebGLUniformLocation, x: number, y: number, z: number): void;
uniform3fv(location: WebGLUniformLocation, v: any): void;
uniform3fv(location: WebGLUniformLocation, v: Float32Array): void;
uniform3i(location: WebGLUniformLocation, x: number, y: number, z: number): void;
uniform3iv(location: WebGLUniformLocation, v: Int32Array): void;
uniform4f(location: WebGLUniformLocation, x: number, y: number, z: number, w: number): void;
uniform4fv(location: WebGLUniformLocation, v: any): void;
uniform4fv(location: WebGLUniformLocation, v: Float32Array): void;
uniform4i(location: WebGLUniformLocation, x: number, y: number, z: number, w: number): void;
uniform4iv(location: WebGLUniformLocation, v: Int32Array): void;
uniformMatrix2fv(location: WebGLUniformLocation, transpose: boolean, value: any): void;
uniformMatrix3fv(location: WebGLUniformLocation, transpose: boolean, value: any): void;
uniformMatrix4fv(location: WebGLUniformLocation, transpose: boolean, value: any): void;
uniformMatrix2fv(location: WebGLUniformLocation, transpose: boolean, value: Float32Array): void;
uniformMatrix3fv(location: WebGLUniformLocation, transpose: boolean, value: Float32Array): void;
uniformMatrix4fv(location: WebGLUniformLocation, transpose: boolean, value: Float32Array): void;
useProgram(program: WebGLProgram): void;
validateProgram(program: WebGLProgram): void;
vertexAttrib1f(indx: number, x: number): void;
vertexAttrib1fv(indx: number, values: any): void;
vertexAttrib1fv(indx: number, values: Float32Array): void;
vertexAttrib2f(indx: number, x: number, y: number): void;
vertexAttrib2fv(indx: number, values: any): void;
vertexAttrib2fv(indx: number, values: Float32Array): void;
vertexAttrib3f(indx: number, x: number, y: number, z: number): void;
vertexAttrib3fv(indx: number, values: any): void;
vertexAttrib3fv(indx: number, values: Float32Array): void;
vertexAttrib4f(indx: number, x: number, y: number, z: number, w: number): void;
vertexAttrib4fv(indx: number, values: any): void;
vertexAttrib4fv(indx: number, values: Float32Array): void;
vertexAttribPointer(indx: number, size: number, type: number, normalized: boolean, stride: number, offset: number): void;
viewport(x: number, y: number, width: number, height: number): void;
ACTIVE_ATTRIBUTES: number;
+1 -1
View File
@@ -17,7 +17,7 @@ interface AudioBuffer {
length: number;
numberOfChannels: number;
sampleRate: number;
getChannelData(channel: number): any;
getChannelData(channel: number): Float32Array;
}
declare var AudioBuffer: {
+10 -10
View File
@@ -11,7 +11,7 @@ namespace ts.server {
input: process.stdin,
output: process.stdout,
terminal: false,
});
});
class Logger implements ts.server.Logger {
fd = -1;
@@ -58,7 +58,7 @@ namespace ts.server {
isVerbose() {
return this.loggingEnabled() && (this.level == "verbose");
}
msg(s: string, type = "Err") {
if (this.fd < 0) {
@@ -85,7 +85,7 @@ namespace ts.server {
interface WatchedFile {
fileName: string;
callback: (fileName: string) => void;
callback: (fileName: string, removed: boolean) => void;
mtime: Date;
}
@@ -121,11 +121,11 @@ namespace ts.server {
fs.stat(watchedFile.fileName,(err, stats) => {
if (err) {
watchedFile.callback(watchedFile.fileName);
watchedFile.callback(watchedFile.fileName, /* removed */ false);
}
else if (watchedFile.mtime.getTime() !== stats.mtime.getTime()) {
watchedFile.mtime = WatchedFileSet.getModifiedTime(watchedFile.fileName);
watchedFile.callback(watchedFile.fileName);
watchedFile.callback(watchedFile.fileName, watchedFile.mtime.getTime() === 0);
}
});
}
@@ -153,7 +153,7 @@ namespace ts.server {
}, this.interval);
}
addFile(fileName: string, callback: (fileName: string) => void ): WatchedFile {
addFile(fileName: string, callback: (fileName: string, removed: boolean) => void ): WatchedFile {
var file: WatchedFile = {
fileName,
callback,
@@ -170,7 +170,7 @@ namespace ts.server {
removeFile(file: WatchedFile) {
this.watchedFiles = WatchedFileSet.copyListRemovingItem(file, this.watchedFiles);
}
}
}
class IOSession extends Session {
constructor(host: ServerHost, logger: ts.server.Logger) {
@@ -243,11 +243,11 @@ namespace ts.server {
// TODO: check that this location is writable
var logger = createLoggerFromEnv();
// REVIEW: for now this implementation uses polling.
// The advantage of polling is that it works reliably
// on all os and with network mounted files.
// For 90 referenced files, the average time to detect
// For 90 referenced files, the average time to detect
// changes is 2*msInterval (by default 5 seconds).
// The overhead of this is .04 percent (1/2500) with
// average pause of < 1 millisecond (and max
@@ -271,4 +271,4 @@ namespace ts.server {
});
// Start listening
ioSession.listen();
}
}
+21 -21
View File
@@ -325,7 +325,7 @@ namespace ts.formatting {
let lastIndentedLine: number;
let indentationOnLastIndentedLine: number;
let edits: TextChange[] = [];
formattingScanner.advance();
@@ -354,12 +354,12 @@ namespace ts.formatting {
* If list element is in the range - its indentation will be equal
* to inherited indentation from its predecessors.
*/
function tryComputeIndentationForListItem(startPos: number,
endPos: number,
parentStartLine: number,
range: TextRange,
function tryComputeIndentationForListItem(startPos: number,
endPos: number,
parentStartLine: number,
range: TextRange,
inheritedIndentation: number): number {
if (rangeOverlapsWithStartEnd(range, startPos, endPos)) {
if (inheritedIndentation !== Constants.Unknown) {
return inheritedIndentation;
@@ -376,7 +376,7 @@ namespace ts.formatting {
return Constants.Unknown;
}
function computeIndentation(
node: TextRangeWithKind,
startLine: number,
@@ -419,8 +419,8 @@ namespace ts.formatting {
// if node is located on the same line with the parent
// - inherit indentation from the parent
// - push children if either parent of node itself has non-zero delta
indentation = startLine === lastIndentedLine
? indentationOnLastIndentedLine
indentation = startLine === lastIndentedLine
? indentationOnLastIndentedLine
: parentDynamicIndentation.getIndentation();
delta = Math.min(options.IndentSize, parentDynamicIndentation.getDelta() + delta);
}
@@ -586,7 +586,7 @@ namespace ts.formatting {
if (!rangeOverlapsWithStartEnd(originalRange, child.pos, child.end)) {
return inheritedIndentation;
}
if (child.getFullWidth() === 0) {
return inheritedIndentation;
}
@@ -624,8 +624,8 @@ namespace ts.formatting {
return inheritedIndentation;
}
function processChildNodes(nodes: NodeArray<Node>,
parent: Node,
function processChildNodes(nodes: NodeArray<Node>,
parent: Node,
parentStartLine: number,
parentDynamicIndentation: DynamicIndentation): void {
@@ -751,7 +751,7 @@ namespace ts.formatting {
// indent token only if is it is in target range and does not overlap with any error ranges
if (tokenIndentation !== Constants.Unknown) {
insertIndentation(currentTokenInfo.token.pos, tokenIndentation, lineAdded);
lastIndentedLine = tokenStart.line;
indentationOnLastIndentedLine = tokenIndentation;
}
@@ -772,12 +772,12 @@ namespace ts.formatting {
}
}
function processRange(range: TextRangeWithKind,
rangeStart: LineAndCharacter,
parent: Node,
contextNode: Node,
function processRange(range: TextRangeWithKind,
rangeStart: LineAndCharacter,
parent: Node,
contextNode: Node,
dynamicIndentation: DynamicIndentation): boolean {
let rangeHasError = rangeContainsError(range);
let lineAdded: boolean;
if (!rangeHasError && !previousRangeHasError) {
@@ -787,7 +787,7 @@ namespace ts.formatting {
trimTrailingWhitespacesForLines(originalStart.line, rangeStart.line);
}
else {
lineAdded =
lineAdded =
processPair(range, rangeStart.line, parent, previousRange, previousRangeStartLine, previousParent, contextNode, dynamicIndentation)
}
}
@@ -933,8 +933,8 @@ namespace ts.formatting {
let lineStartPosition = getStartPositionOfLine(line, sourceFile);
let lineEndPosition = getEndLinePosition(line, sourceFile);
// do not trim whitespaces in comments
if (range && isComment(range.kind) && range.pos <= lineEndPosition && range.end > lineEndPosition) {
// do not trim whitespaces in comments or template expression
if (range && (isComment(range.kind) || isStringOrRegularExpressionOrTemplateLiteral(range.kind)) && range.pos <= lineEndPosition && range.end > lineEndPosition) {
continue;
}
+19 -2
View File
@@ -3,8 +3,14 @@
/* @internal */
namespace ts.formatting {
let scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false);
const standardScanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false, LanguageVariant.Standard);
const jsxScanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false, LanguageVariant.JSX);
/**
* Scanner that is currently used for formatting
*/
let scanner: Scanner;
export interface FormattingScanner {
advance(): void;
isOnToken(): boolean;
@@ -22,6 +28,8 @@ namespace ts.formatting {
}
export function getFormattingScanner(sourceFile: SourceFile, startPos: number, endPos: number): FormattingScanner {
Debug.assert(scanner === undefined);
scanner = sourceFile.languageVariant === LanguageVariant.JSX ? jsxScanner : standardScanner;
scanner.setText(sourceFile.text);
scanner.setTextPos(startPos);
@@ -40,12 +48,17 @@ namespace ts.formatting {
isOnToken: isOnToken,
lastTrailingTriviaWasNewLine: () => wasNewLine,
close: () => {
Debug.assert(scanner !== undefined);
lastTokenInfo = undefined;
scanner.setText(undefined);
scanner = undefined;
}
}
function advance(): void {
Debug.assert(scanner !== undefined);
lastTokenInfo = undefined;
let isStarted = scanner.getStartPos() !== startPos;
@@ -138,6 +151,8 @@ namespace ts.formatting {
}
function readTokenInfo(n: Node): TokenInfo {
Debug.assert(scanner !== undefined);
if (!isOnToken()) {
// scanner is not on the token (either advance was not called yet or scanner is already past the end position)
return {
@@ -245,6 +260,8 @@ namespace ts.formatting {
}
function isOnToken(): boolean {
Debug.assert(scanner !== undefined);
let current = (lastTokenInfo && lastTokenInfo.token.kind) || scanner.getToken();
let startPos = (lastTokenInfo && lastTokenInfo.token.pos) || scanner.getStartPos();
return startPos < endPos && current !== SyntaxKind.EndOfFileToken && !isTrivia(current);
+6 -2
View File
@@ -216,8 +216,10 @@ namespace ts.formatting {
// Async functions
public SpaceBetweenAsyncAndFunctionKeyword: Rule;
// Tagged template string
// Template strings
public SpaceBetweenTagAndTemplateString: Rule;
public NoSpaceAfterTemplateHeadAndMiddle: Rule;
public NoSpaceBeforeTemplateMiddleAndTail: Rule;
constructor() {
///
@@ -371,6 +373,8 @@ namespace ts.formatting {
// template string
this.SpaceBetweenTagAndTemplateString = new Rule(RuleDescriptor.create3(SyntaxKind.Identifier, Shared.TokenRange.FromTokens([SyntaxKind.NoSubstitutionTemplateLiteral, SyntaxKind.TemplateHead])), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Space));
this.NoSpaceAfterTemplateHeadAndMiddle = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.TemplateHead, SyntaxKind.TemplateMiddle]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete));
this.NoSpaceBeforeTemplateMiddleAndTail = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.FromTokens([SyntaxKind.TemplateMiddle, SyntaxKind.TemplateTail])), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete));
// These rules are higher in priority than user-configurable rules.
this.HighPriorityCommonRules =
@@ -399,7 +403,7 @@ namespace ts.formatting {
this.SpaceBeforeBinaryKeywordOperator, this.SpaceAfterBinaryKeywordOperator,
this.SpaceAfterVoidOperator,
this.SpaceBetweenAsyncAndFunctionKeyword,
this.SpaceBetweenTagAndTemplateString,
this.SpaceBetweenTagAndTemplateString, this.NoSpaceAfterTemplateHeadAndMiddle, this.NoSpaceBeforeTemplateMiddleAndTail,
// TypeScript-specific rules
this.NoSpaceAfterConstructor, this.NoSpaceAfterModuleImport,
+2 -7
View File
@@ -19,13 +19,7 @@ namespace ts.formatting {
}
// no indentation in string \regex\template literals
let precedingTokenIsLiteral =
precedingToken.kind === SyntaxKind.StringLiteral ||
precedingToken.kind === SyntaxKind.RegularExpressionLiteral ||
precedingToken.kind === SyntaxKind.NoSubstitutionTemplateLiteral ||
precedingToken.kind === SyntaxKind.TemplateHead ||
precedingToken.kind === SyntaxKind.TemplateMiddle ||
precedingToken.kind === SyntaxKind.TemplateTail;
let precedingTokenIsLiteral = isStringOrRegularExpressionOrTemplateLiteral(precedingToken.kind);
if (precedingTokenIsLiteral && precedingToken.getStart(sourceFile) <= position && precedingToken.end > position) {
return 0;
}
@@ -405,6 +399,7 @@ namespace ts.formatting {
function nodeContentIsAlwaysIndented(kind: SyntaxKind): boolean {
switch (kind) {
case SyntaxKind.ExpressionStatement:
case SyntaxKind.ClassDeclaration:
case SyntaxKind.ClassExpression:
case SyntaxKind.InterfaceDeclaration:
+108 -20
View File
@@ -725,7 +725,7 @@ namespace ts {
}
getBaseTypes(): ObjectType[] {
return this.flags & (TypeFlags.Class | TypeFlags.Interface)
? this.checker.getBaseTypes(<TypeObject & InterfaceType>this)
? this.checker.getBaseTypes(<InterfaceType><Type>this)
: undefined;
}
}
@@ -3386,6 +3386,9 @@ namespace ts {
if (parent && (parent.kind === SyntaxKind.JsxSelfClosingElement || parent.kind === SyntaxKind.JsxOpeningElement)) {
return <JsxOpeningLikeElement>parent;
}
else if (parent.kind === SyntaxKind.JsxAttribute) {
return <JsxOpeningLikeElement>parent.parent;
}
break;
// The context token is the closing } or " of an attribute, which means
@@ -3496,9 +3499,9 @@ namespace ts {
return containingNodeKind === SyntaxKind.Parameter;
case SyntaxKind.AsKeyword:
containingNodeKind === SyntaxKind.ImportSpecifier ||
containingNodeKind === SyntaxKind.ExportSpecifier ||
containingNodeKind === SyntaxKind.NamespaceImport;
return containingNodeKind === SyntaxKind.ImportSpecifier ||
containingNodeKind === SyntaxKind.ExportSpecifier ||
containingNodeKind === SyntaxKind.NamespaceImport;
case SyntaxKind.ClassKeyword:
case SyntaxKind.EnumKeyword:
@@ -3517,14 +3520,20 @@ namespace ts {
// Previous token may have been a keyword that was converted to an identifier.
switch (contextToken.getText()) {
case "abstract":
case "async":
case "class":
case "interface":
case "const":
case "declare":
case "enum":
case "function":
case "var":
case "static":
case "interface":
case "let":
case "const":
case "private":
case "protected":
case "public":
case "static":
case "var":
case "yield":
return true;
}
@@ -6086,7 +6095,8 @@ namespace ts {
}
return node.parent.kind === SyntaxKind.TypeReference ||
(node.parent.kind === SyntaxKind.ExpressionWithTypeArguments && !isExpressionWithTypeArgumentsInClassExtendsClause(<ExpressionWithTypeArguments>node.parent));
(node.parent.kind === SyntaxKind.ExpressionWithTypeArguments && !isExpressionWithTypeArgumentsInClassExtendsClause(<ExpressionWithTypeArguments>node.parent)) ||
node.kind === SyntaxKind.ThisKeyword && !isExpression(node);
}
function isNamespaceReference(node: Node): boolean {
@@ -6834,8 +6844,12 @@ namespace ts {
* Checks if position points to a valid position to add JSDoc comments, and if so,
* returns the appropriate template. Otherwise returns an empty string.
* Valid positions are
* - outside of comments, statements, and expressions, and
* - preceding a function declaration.
* - outside of comments, statements, and expressions, and
* - preceding a:
* - function/constructor/method declaration
* - class declarations
* - variable statements
* - namespace declarations
*
* Hosts should ideally check that:
* - The line is all whitespace up to 'position' before performing the insertion.
@@ -6862,16 +6876,37 @@ namespace ts {
}
// TODO: add support for:
// - methods
// - constructors
// - class decls
let containingFunction = <FunctionDeclaration>getAncestor(tokenAtPos, SyntaxKind.FunctionDeclaration);
// - enums/enum members
// - interfaces
// - property declarations
// - potentially property assignments
let commentOwner: Node;
findOwner: for (commentOwner = tokenAtPos; commentOwner; commentOwner = commentOwner.parent) {
switch (commentOwner.kind) {
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.MethodDeclaration:
case SyntaxKind.Constructor:
case SyntaxKind.ClassDeclaration:
case SyntaxKind.VariableStatement:
break findOwner;
case SyntaxKind.SourceFile:
return undefined;
case SyntaxKind.ModuleDeclaration:
// If in walking up the tree, we hit a a nested namespace declaration,
// then we must be somewhere within a dotted namespace name; however we don't
// want to give back a JSDoc template for the 'b' or 'c' in 'namespace a.b.c { }'.
if (commentOwner.parent.kind === SyntaxKind.ModuleDeclaration) {
return undefined;
}
break findOwner;
}
}
if (!containingFunction || containingFunction.getStart() < position) {
if (!commentOwner || commentOwner.getStart() < position) {
return undefined;
}
let parameters = containingFunction.parameters;
let parameters = getParametersForJsDocOwningNode(commentOwner);
let posLineAndChar = sourceFile.getLineAndCharacterOfPosition(position);
let lineStart = sourceFile.getLineStarts()[posLineAndChar.line];
@@ -6880,9 +6915,15 @@ namespace ts {
// TODO: call a helper method instead once PR #4133 gets merged in.
const newLine = host.getNewLine ? host.getNewLine() : "\r\n";
let docParams = parameters.reduce((prev, cur, index) =>
prev +
indentationStr + " * @param " + (cur.name.kind === SyntaxKind.Identifier ? (<Identifier>cur.name).text : "param" + index) + newLine, "");
let docParams = "";
for (let i = 0, numParams = parameters.length; i < numParams; i++) {
const currentName = parameters[i].name;
const paramName = currentName.kind === SyntaxKind.Identifier ?
(<Identifier>currentName).text :
"param" + i;
docParams += `${indentationStr} * @param ${paramName}${newLine}`;
}
// A doc comment consists of the following
// * The opening comment line
@@ -6902,6 +6943,52 @@ namespace ts {
return { newText: result, caretOffset: preamble.length };
}
function getParametersForJsDocOwningNode(commentOwner: Node): ParameterDeclaration[] {
if (isFunctionLike(commentOwner)) {
return commentOwner.parameters;
}
if (commentOwner.kind === SyntaxKind.VariableStatement) {
const varStatement = <VariableStatement>commentOwner;
const varDeclarations = varStatement.declarationList.declarations;
if (varDeclarations.length === 1 && varDeclarations[0].initializer) {
return getParametersFromRightHandSideOfAssignment(varDeclarations[0].initializer);
}
}
return emptyArray;
}
/**
* Digs into an an initializer or RHS operand of an assignment operation
* to get the parameters of an apt signature corresponding to a
* function expression or a class expression.
*
* @param rightHandSide the expression which may contain an appropriate set of parameters
* @returns the parameters of a signature found on the RHS if one exists; otherwise 'emptyArray'.
*/
function getParametersFromRightHandSideOfAssignment(rightHandSide: Expression): ParameterDeclaration[] {
while (rightHandSide.kind === SyntaxKind.ParenthesizedExpression) {
rightHandSide = (<ParenthesizedExpression>rightHandSide).expression;
}
switch (rightHandSide.kind) {
case SyntaxKind.FunctionExpression:
case SyntaxKind.ArrowFunction:
return (<FunctionExpression>rightHandSide).parameters;
case SyntaxKind.ClassExpression:
for (let member of (<ClassExpression>rightHandSide).members) {
if (member.kind === SyntaxKind.Constructor) {
return (<ConstructorDeclaration>member).parameters;
}
}
break;
}
return emptyArray;
}
function getTodoComments(fileName: string, descriptors: TodoCommentDescriptor[]): TodoComment[] {
// Note: while getting todo comments seems like a syntactic operation, we actually
// treat it as a semantic operation here. This is because we expect our host to call
@@ -7571,6 +7658,7 @@ namespace ts {
case SyntaxKind.GreaterThanEqualsToken:
case SyntaxKind.InstanceOfKeyword:
case SyntaxKind.InKeyword:
case SyntaxKind.AsKeyword:
case SyntaxKind.EqualsEqualsToken:
case SyntaxKind.ExclamationEqualsToken:
case SyntaxKind.EqualsEqualsEqualsToken:
+20 -9
View File
@@ -9,7 +9,7 @@ namespace ts {
export function getEndLinePosition(line: number, sourceFile: SourceFile): number {
Debug.assert(line >= 0);
let lineStarts = sourceFile.getLineStarts();
let lineIndex = line;
if (lineIndex + 1 === lineStarts.length) {
// last line - return EOF
@@ -128,7 +128,8 @@ namespace ts {
return isCompletedNode((<IfStatement>n).thenStatement, sourceFile);
case SyntaxKind.ExpressionStatement:
return isCompletedNode((<ExpressionStatement>n).expression, sourceFile);
return isCompletedNode((<ExpressionStatement>n).expression, sourceFile) ||
hasChildOfKind(n, SyntaxKind.SemicolonToken);
case SyntaxKind.ArrayLiteralExpression:
case SyntaxKind.ArrayBindingPattern:
@@ -170,7 +171,7 @@ namespace ts {
case SyntaxKind.VoidExpression:
case SyntaxKind.YieldExpression:
case SyntaxKind.SpreadElementExpression:
let unaryWordExpression = (<TypeOfExpression|DeleteExpression|VoidExpression|YieldExpression|SpreadElementExpression>n);
let unaryWordExpression = (<TypeOfExpression | DeleteExpression | VoidExpression | YieldExpression | SpreadElementExpression>n);
return isCompletedNode(unaryWordExpression.expression, sourceFile);
case SyntaxKind.TaggedTemplateExpression:
@@ -252,7 +253,7 @@ namespace ts {
});
// Either we didn't find an appropriate list, or the list must contain us.
Debug.assert(!syntaxList || contains(syntaxList.getChildren(), node));
Debug.assert(!syntaxList || contains(syntaxList.getChildren(), node));
return syntaxList;
}
@@ -388,7 +389,7 @@ namespace ts {
// if this is the case - then we should assume that token in question is located in previous child.
if (position < child.end && (nodeHasTokens(child) || child.kind === SyntaxKind.JsxText)) {
const start = child.getStart(sourceFile);
const lookInPreviousChild =
const lookInPreviousChild =
(start >= position) || // cursor in the leading trivia
(child.kind === SyntaxKind.JsxText && start === child.end); // whitespace only JsxText
@@ -425,7 +426,7 @@ namespace ts {
}
}
}
export function isInString(sourceFile: SourceFile, position: number) {
let token = getTokenAtPosition(sourceFile, position);
return token && token.kind === SyntaxKind.StringLiteral && position > token.getStart();
@@ -473,7 +474,7 @@ namespace ts {
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] === '*';
@@ -562,6 +563,15 @@ namespace ts {
return kind === SyntaxKind.SingleLineCommentTrivia || kind === SyntaxKind.MultiLineCommentTrivia;
}
export function isStringOrRegularExpressionOrTemplateLiteral(kind: SyntaxKind): boolean {
if (kind === SyntaxKind.StringLiteral
|| kind === SyntaxKind.RegularExpressionLiteral
|| isTemplateLiteralKind(kind)) {
return true;
}
return false;
}
export function isPunctuation(kind: SyntaxKind): boolean {
return SyntaxKind.FirstPunctuation <= kind && kind <= SyntaxKind.LastPunctuation;
}
@@ -626,7 +636,8 @@ namespace ts {
increaseIndent: () => { indent++; },
decreaseIndent: () => { indent--; },
clear: resetWriter,
trackSymbol: () => { }
trackSymbol: () => { },
reportInaccessibleThisError: () => { }
};
function writeIndent() {
@@ -689,7 +700,7 @@ namespace ts {
}
export function displayPart(text: string, kind: SymbolDisplayPartKind, symbol?: Symbol): SymbolDisplayPart {
return <SymbolDisplayPart> {
return <SymbolDisplayPart>{
text: text,
kind: SymbolDisplayPartKind[kind]
};
+1 -1
View File
@@ -28,7 +28,7 @@ class Board {
>this.ships.every(function (val) { return val.isSunk; }) : boolean
>this.ships.every : (callbackfn: (value: Ship, index: number, array: Ship[]) => boolean, thisArg?: any) => boolean
>this.ships : Ship[]
>this : Board
>this : this
>ships : Ship[]
>every : (callbackfn: (value: Ship, index: number, array: Ship[]) => boolean, thisArg?: any) => boolean
>function (val) { return val.isSunk; } : (val: Ship) => boolean
@@ -15,11 +15,11 @@ class Point {
>"x=" + this.x : string
>"x=" : string
>this.x : number
>this : Point
>this : this
>x : number
>" y=" : string
>this.y : number
>this : Point
>this : this
>y : number
}
}
@@ -50,7 +50,7 @@ class ColoredPoint extends Point {
>toString : () => string
>" color=" : string
>this.color : string
>this : ColoredPoint
>this : this
>color : string
}
}
@@ -26,7 +26,7 @@ class C2 {
return this.x;
>this.x : IHasVisualizationModel
>this : C2
>this : this
>x : IHasVisualizationModel
}
set A(x) {
@@ -1,17 +1,14 @@
tests/cases/compiler/ambientEnum1.ts(2,9): error TS1066: Ambient enum elements can only have integer literal initializers.
tests/cases/compiler/ambientEnum1.ts(7,9): error TS1066: Ambient enum elements can only have integer literal initializers.
tests/cases/compiler/ambientEnum1.ts(7,13): error TS1066: In ambient enum declarations member initializer must be constant expression.
==== tests/cases/compiler/ambientEnum1.ts (2 errors) ====
==== tests/cases/compiler/ambientEnum1.ts (1 errors) ====
declare enum E1 {
y = 4.23
~
!!! error TS1066: Ambient enum elements can only have integer literal initializers.
}
// Ambient enum with computer member
declare enum E2 {
x = 'foo'.length
~
!!! error TS1066: Ambient enum elements can only have integer literal initializers.
~~~~~~~~~~~~
!!! error TS1066: In ambient enum declarations member initializer must be constant expression.
}
@@ -1,24 +0,0 @@
tests/cases/conformance/ambient/ambientEnumDeclaration1.ts(5,5): error TS1066: Ambient enum elements can only have integer literal initializers.
tests/cases/conformance/ambient/ambientEnumDeclaration1.ts(6,5): error TS1066: Ambient enum elements can only have integer literal initializers.
tests/cases/conformance/ambient/ambientEnumDeclaration1.ts(7,5): error TS1066: Ambient enum elements can only have integer literal initializers.
tests/cases/conformance/ambient/ambientEnumDeclaration1.ts(8,5): error TS1066: Ambient enum elements can only have integer literal initializers.
==== tests/cases/conformance/ambient/ambientEnumDeclaration1.ts (4 errors) ====
// In ambient enum declarations, all values specified in enum member declarations must be classified as constant enum expressions.
declare enum E {
a = 10,
b = 10 + 1,
~
!!! error TS1066: Ambient enum elements can only have integer literal initializers.
c = b,
~
!!! error TS1066: Ambient enum elements can only have integer literal initializers.
d = (c) + 1,
~
!!! error TS1066: Ambient enum elements can only have integer literal initializers.
e = 10 << 2 * 8,
~
!!! error TS1066: Ambient enum elements can only have integer literal initializers.
}
@@ -0,0 +1,23 @@
=== tests/cases/conformance/ambient/ambientEnumDeclaration1.ts ===
// In ambient enum declarations, all values specified in enum member declarations must be classified as constant enum expressions.
declare enum E {
>E : Symbol(E, Decl(ambientEnumDeclaration1.ts, 0, 0))
a = 10,
>a : Symbol(E.a, Decl(ambientEnumDeclaration1.ts, 2, 16))
b = 10 + 1,
>b : Symbol(E.b, Decl(ambientEnumDeclaration1.ts, 3, 11))
c = b,
>c : Symbol(E.c, Decl(ambientEnumDeclaration1.ts, 4, 15))
>b : Symbol(E.b, Decl(ambientEnumDeclaration1.ts, 3, 11))
d = (c) + 1,
>d : Symbol(E.d, Decl(ambientEnumDeclaration1.ts, 5, 10))
>c : Symbol(E.c, Decl(ambientEnumDeclaration1.ts, 4, 15))
e = 10 << 2 * 8,
>e : Symbol(E.e, Decl(ambientEnumDeclaration1.ts, 6, 16))
}
@@ -0,0 +1,35 @@
=== tests/cases/conformance/ambient/ambientEnumDeclaration1.ts ===
// In ambient enum declarations, all values specified in enum member declarations must be classified as constant enum expressions.
declare enum E {
>E : E
a = 10,
>a : E
>10 : number
b = 10 + 1,
>b : E
>10 + 1 : number
>10 : number
>1 : number
c = b,
>c : E
>b : E
d = (c) + 1,
>d : E
>(c) + 1 : number
>(c) : E
>c : E
>1 : number
e = 10 << 2 * 8,
>e : E
>10 << 2 * 8 : number
>10 : number
>2 * 8 : number
>2 : number
>8 : number
}
@@ -1,9 +0,0 @@
tests/cases/compiler/ambientEnumElementInitializer3.ts(2,2): error TS1066: Ambient enum elements can only have integer literal initializers.
==== tests/cases/compiler/ambientEnumElementInitializer3.ts (1 errors) ====
declare enum E {
e = 3.3 // Decimal
~
!!! error TS1066: Ambient enum elements can only have integer literal initializers.
}
@@ -0,0 +1,7 @@
=== tests/cases/compiler/ambientEnumElementInitializer3.ts ===
declare enum E {
>E : Symbol(E, Decl(ambientEnumElementInitializer3.ts, 0, 0))
e = 3.3 // Decimal
>e : Symbol(E.e, Decl(ambientEnumElementInitializer3.ts, 0, 16))
}
@@ -0,0 +1,8 @@
=== tests/cases/compiler/ambientEnumElementInitializer3.ts ===
declare enum E {
>E : E
e = 3.3 // Decimal
>e : E
>3.3 : number
}
@@ -2,8 +2,7 @@ tests/cases/conformance/ambient/ambientErrors.ts(2,15): error TS1039: Initialize
tests/cases/conformance/ambient/ambientErrors.ts(6,18): error TS2382: Specialized overload signature is not assignable to any non-specialized signature.
tests/cases/conformance/ambient/ambientErrors.ts(17,22): error TS2371: A parameter initializer is only allowed in a function or constructor implementation.
tests/cases/conformance/ambient/ambientErrors.ts(20,24): error TS1183: An implementation cannot be declared in ambient contexts.
tests/cases/conformance/ambient/ambientErrors.ts(24,5): error TS1066: Ambient enum elements can only have integer literal initializers.
tests/cases/conformance/ambient/ambientErrors.ts(29,5): error TS1066: Ambient enum elements can only have integer literal initializers.
tests/cases/conformance/ambient/ambientErrors.ts(29,9): error TS1066: In ambient enum declarations member initializer must be constant expression.
tests/cases/conformance/ambient/ambientErrors.ts(34,11): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/conformance/ambient/ambientErrors.ts(35,19): error TS1183: An implementation cannot be declared in ambient contexts.
tests/cases/conformance/ambient/ambientErrors.ts(37,20): error TS1039: Initializers are not allowed in ambient contexts.
@@ -11,12 +10,12 @@ tests/cases/conformance/ambient/ambientErrors.ts(38,13): error TS1039: Initializ
tests/cases/conformance/ambient/ambientErrors.ts(39,23): error TS1183: An implementation cannot be declared in ambient contexts.
tests/cases/conformance/ambient/ambientErrors.ts(40,14): error TS1183: An implementation cannot be declared in ambient contexts.
tests/cases/conformance/ambient/ambientErrors.ts(41,22): error TS1183: An implementation cannot be declared in ambient contexts.
tests/cases/conformance/ambient/ambientErrors.ts(47,20): error TS2435: Ambient modules cannot be nested in other modules.
tests/cases/conformance/ambient/ambientErrors.ts(47,20): error TS2435: Ambient modules cannot be nested in other modules or namespaces.
tests/cases/conformance/ambient/ambientErrors.ts(51,16): error TS2436: Ambient module declaration cannot specify relative module name.
tests/cases/conformance/ambient/ambientErrors.ts(57,5): error TS2309: An export assignment cannot be used in a module with other exported elements.
==== tests/cases/conformance/ambient/ambientErrors.ts (16 errors) ====
==== tests/cases/conformance/ambient/ambientErrors.ts (15 errors) ====
// Ambient variable with an initializer
declare var x = 4;
~
@@ -49,15 +48,13 @@ tests/cases/conformance/ambient/ambientErrors.ts(57,5): error TS2309: An export
// Ambient enum with non - integer literal constant member
declare enum E1 {
y = 4.23
~
!!! error TS1066: Ambient enum elements can only have integer literal initializers.
}
// Ambient enum with computer member
declare enum E2 {
x = 'foo'.length
~
!!! error TS1066: Ambient enum elements can only have integer literal initializers.
~~~~~~~~~~~~
!!! error TS1066: In ambient enum declarations member initializer must be constant expression.
}
// Ambient module with initializers for values, bodies for functions / classes
@@ -91,7 +88,7 @@ tests/cases/conformance/ambient/ambientErrors.ts(57,5): error TS2309: An export
module M2 {
declare module 'nope' { }
~~~~~~
!!! error TS2435: Ambient modules cannot be nested in other modules.
!!! error TS2435: Ambient modules cannot be nested in other modules or namespaces.
}
// Ambient external module with a string literal name that isn't a top level external module name
@@ -1,4 +1,4 @@
tests/cases/compiler/ambientExternalModuleInAnotherExternalModule.ts(5,16): error TS2435: Ambient modules cannot be nested in other modules.
tests/cases/compiler/ambientExternalModuleInAnotherExternalModule.ts(5,16): error TS2435: Ambient modules cannot be nested in other modules or namespaces.
tests/cases/compiler/ambientExternalModuleInAnotherExternalModule.ts(10,22): error TS2307: Cannot find module 'ext'.
@@ -9,7 +9,7 @@ tests/cases/compiler/ambientExternalModuleInAnotherExternalModule.ts(10,22): err
declare module "ext" {
~~~~~
!!! error TS2435: Ambient modules cannot be nested in other modules.
!!! error TS2435: Ambient modules cannot be nested in other modules or namespaces.
export class C { }
}
@@ -1,9 +1,9 @@
tests/cases/conformance/ambient/ambientExternalModuleInsideNonAmbient.ts(2,27): error TS2435: Ambient modules cannot be nested in other modules.
tests/cases/conformance/ambient/ambientExternalModuleInsideNonAmbient.ts(2,27): error TS2435: Ambient modules cannot be nested in other modules or namespaces.
==== tests/cases/conformance/ambient/ambientExternalModuleInsideNonAmbient.ts (1 errors) ====
module M {
export declare module "M" { }
~~~
!!! error TS2435: Ambient modules cannot be nested in other modules.
!!! error TS2435: Ambient modules cannot be nested in other modules or namespaces.
}
@@ -1,7 +1,7 @@
tests/cases/conformance/ambient/ambientExternalModuleInsideNonAmbientExternalModule.ts(1,23): error TS2435: Ambient modules cannot be nested in other modules.
tests/cases/conformance/ambient/ambientExternalModuleInsideNonAmbientExternalModule.ts(1,23): error TS2435: Ambient modules cannot be nested in other modules or namespaces.
==== tests/cases/conformance/ambient/ambientExternalModuleInsideNonAmbientExternalModule.ts (1 errors) ====
export declare module "M" { }
~~~
!!! error TS2435: Ambient modules cannot be nested in other modules.
!!! error TS2435: Ambient modules cannot be nested in other modules or namespaces.
@@ -31,7 +31,7 @@ class TestClass {
this.bar(x); // should not error
>this.bar(x) : void
>this.bar : { (x: string): void; (x: string[]): void; }
>this : TestClass
>this : this
>bar : { (x: string): void; (x: string[]): void; }
>x : any
}
@@ -71,7 +71,7 @@ class TestClass2 {
return this.bar(x); // should not error
>this.bar(x) : number
>this.bar : { (x: string): number; (x: string[]): number; }
>this : TestClass2
>this : this
>bar : { (x: string): number; (x: string[]): number; }
>x : any
}
@@ -10,7 +10,7 @@ class Foo {
this.x = 5;
>this.x = 5 : number
>this.x : number
>this : Foo
>this : this
>x : number
>5 : number
}
@@ -34,6 +34,8 @@ tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(25,5): error
tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(26,5): error TS2322: Type 'StrNum' is not assignable to type '[string]'.
Types of property 'pop' are incompatible.
Type '() => string | number' is not assignable to type '() => string'.
Type 'string | number' is not assignable to type 'string'.
Type 'number' is not assignable to type 'string'.
tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(27,5): error TS2322: Type '{ 0: string; 1: number; }' is not assignable to type '[string]'.
Property 'length' is missing in type '{ 0: string; 1: number; }'.
tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(28,5): error TS2322: Type '[string, number]' is not assignable to type '[number, string]'.
@@ -125,6 +127,8 @@ tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(30,5): error
!!! error TS2322: Type 'StrNum' is not assignable to type '[string]'.
!!! error TS2322: Types of property 'pop' are incompatible.
!!! error TS2322: Type '() => string | number' is not assignable to type '() => string'.
!!! error TS2322: Type 'string | number' is not assignable to type 'string'.
!!! error TS2322: Type 'number' is not assignable to type 'string'.
var m3: [string] = z;
~~
!!! error TS2322: Type '{ 0: string; 1: number; }' is not assignable to type '[string]'.
@@ -51,7 +51,7 @@ module EmptyTypes {
>(this.voidIfAny([4, 2][0])) : number
>this.voidIfAny([4, 2][0]) : number
>this.voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>this : f
>this : this
>voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>[4, 2][0] : number
>[4, 2] : number[]
@@ -64,7 +64,7 @@ module EmptyTypes {
>(this.voidIfAny([4, 2, undefined][0])) : number
>this.voidIfAny([4, 2, undefined][0]) : number
>this.voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>this : f
>this : this
>voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>[4, 2, undefined][0] : number
>[4, 2, undefined] : number[]
@@ -78,7 +78,7 @@ module EmptyTypes {
>(this.voidIfAny([undefined, 2, 4][0])) : number
>this.voidIfAny([undefined, 2, 4][0]) : number
>this.voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>this : f
>this : this
>voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>[undefined, 2, 4][0] : number
>[undefined, 2, 4] : number[]
@@ -92,7 +92,7 @@ module EmptyTypes {
>(this.voidIfAny([null, 2, 4][0])) : number
>this.voidIfAny([null, 2, 4][0]) : number
>this.voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>this : f
>this : this
>voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>[null, 2, 4][0] : number
>[null, 2, 4] : number[]
@@ -106,7 +106,7 @@ module EmptyTypes {
>(this.voidIfAny([2, 4, null][0])) : number
>this.voidIfAny([2, 4, null][0]) : number
>this.voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>this : f
>this : this
>voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>[2, 4, null][0] : number
>[2, 4, null] : number[]
@@ -120,7 +120,7 @@ module EmptyTypes {
>(this.voidIfAny([undefined, 4, null][0])) : number
>this.voidIfAny([undefined, 4, null][0]) : number
>this.voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>this : f
>this : this
>voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>[undefined, 4, null][0] : number
>[undefined, 4, null] : number[]
@@ -134,7 +134,7 @@ module EmptyTypes {
>(this.voidIfAny(['', "q"][0])) : number
>this.voidIfAny(['', "q"][0]) : number
>this.voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>this : f
>this : this
>voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>['', "q"][0] : string
>['', "q"] : string[]
@@ -147,7 +147,7 @@ module EmptyTypes {
>(this.voidIfAny(['', "q", undefined][0])) : number
>this.voidIfAny(['', "q", undefined][0]) : number
>this.voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>this : f
>this : this
>voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>['', "q", undefined][0] : string
>['', "q", undefined] : string[]
@@ -161,7 +161,7 @@ module EmptyTypes {
>(this.voidIfAny([undefined, "q", ''][0])) : number
>this.voidIfAny([undefined, "q", ''][0]) : number
>this.voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>this : f
>this : this
>voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>[undefined, "q", ''][0] : string
>[undefined, "q", ''] : string[]
@@ -175,7 +175,7 @@ module EmptyTypes {
>(this.voidIfAny([null, "q", ''][0])) : number
>this.voidIfAny([null, "q", ''][0]) : number
>this.voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>this : f
>this : this
>voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>[null, "q", ''][0] : string
>[null, "q", ''] : string[]
@@ -189,7 +189,7 @@ module EmptyTypes {
>(this.voidIfAny(["q", '', null][0])) : number
>this.voidIfAny(["q", '', null][0]) : number
>this.voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>this : f
>this : this
>voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>["q", '', null][0] : string
>["q", '', null] : string[]
@@ -203,7 +203,7 @@ module EmptyTypes {
>(this.voidIfAny([undefined, '', null][0])) : number
>this.voidIfAny([undefined, '', null][0]) : number
>this.voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>this : f
>this : this
>voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>[undefined, '', null][0] : string
>[undefined, '', null] : string[]
@@ -217,7 +217,7 @@ module EmptyTypes {
>(this.voidIfAny([[3, 4], [null]][0][0])) : number
>this.voidIfAny([[3, 4], [null]][0][0]) : number
>this.voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>this : f
>this : this
>voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>[[3, 4], [null]][0][0] : number
>[[3, 4], [null]][0] : number[]
@@ -454,7 +454,7 @@ module NonEmptyTypes {
>(this.voidIfAny([4, 2][0])) : number
>this.voidIfAny([4, 2][0]) : number
>this.voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>this : f
>this : this
>voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>[4, 2][0] : number
>[4, 2] : number[]
@@ -467,7 +467,7 @@ module NonEmptyTypes {
>(this.voidIfAny([4, 2, undefined][0])) : number
>this.voidIfAny([4, 2, undefined][0]) : number
>this.voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>this : f
>this : this
>voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>[4, 2, undefined][0] : number
>[4, 2, undefined] : number[]
@@ -481,7 +481,7 @@ module NonEmptyTypes {
>(this.voidIfAny([undefined, 2, 4][0])) : number
>this.voidIfAny([undefined, 2, 4][0]) : number
>this.voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>this : f
>this : this
>voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>[undefined, 2, 4][0] : number
>[undefined, 2, 4] : number[]
@@ -495,7 +495,7 @@ module NonEmptyTypes {
>(this.voidIfAny([null, 2, 4][0])) : number
>this.voidIfAny([null, 2, 4][0]) : number
>this.voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>this : f
>this : this
>voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>[null, 2, 4][0] : number
>[null, 2, 4] : number[]
@@ -509,7 +509,7 @@ module NonEmptyTypes {
>(this.voidIfAny([2, 4, null][0])) : number
>this.voidIfAny([2, 4, null][0]) : number
>this.voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>this : f
>this : this
>voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>[2, 4, null][0] : number
>[2, 4, null] : number[]
@@ -523,7 +523,7 @@ module NonEmptyTypes {
>(this.voidIfAny([undefined, 4, null][0])) : number
>this.voidIfAny([undefined, 4, null][0]) : number
>this.voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>this : f
>this : this
>voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>[undefined, 4, null][0] : number
>[undefined, 4, null] : number[]
@@ -537,7 +537,7 @@ module NonEmptyTypes {
>(this.voidIfAny(['', "q"][0])) : number
>this.voidIfAny(['', "q"][0]) : number
>this.voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>this : f
>this : this
>voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>['', "q"][0] : string
>['', "q"] : string[]
@@ -550,7 +550,7 @@ module NonEmptyTypes {
>(this.voidIfAny(['', "q", undefined][0])) : number
>this.voidIfAny(['', "q", undefined][0]) : number
>this.voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>this : f
>this : this
>voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>['', "q", undefined][0] : string
>['', "q", undefined] : string[]
@@ -564,7 +564,7 @@ module NonEmptyTypes {
>(this.voidIfAny([undefined, "q", ''][0])) : number
>this.voidIfAny([undefined, "q", ''][0]) : number
>this.voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>this : f
>this : this
>voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>[undefined, "q", ''][0] : string
>[undefined, "q", ''] : string[]
@@ -578,7 +578,7 @@ module NonEmptyTypes {
>(this.voidIfAny([null, "q", ''][0])) : number
>this.voidIfAny([null, "q", ''][0]) : number
>this.voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>this : f
>this : this
>voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>[null, "q", ''][0] : string
>[null, "q", ''] : string[]
@@ -592,7 +592,7 @@ module NonEmptyTypes {
>(this.voidIfAny(["q", '', null][0])) : number
>this.voidIfAny(["q", '', null][0]) : number
>this.voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>this : f
>this : this
>voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>["q", '', null][0] : string
>["q", '', null] : string[]
@@ -606,7 +606,7 @@ module NonEmptyTypes {
>(this.voidIfAny([undefined, '', null][0])) : number
>this.voidIfAny([undefined, '', null][0]) : number
>this.voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>this : f
>this : this
>voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>[undefined, '', null][0] : string
>[undefined, '', null] : string[]
@@ -620,7 +620,7 @@ module NonEmptyTypes {
>(this.voidIfAny([[3, 4], [null]][0][0])) : number
>this.voidIfAny([[3, 4], [null]][0][0]) : number
>this.voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>this : f
>this : this
>voidIfAny : { (x: boolean, y?: boolean): number; (x: string, y?: boolean): number; (x: number, y?: boolean): number; }
>[[3, 4], [null]][0][0] : number
>[[3, 4], [null]][0] : number[]
@@ -18,7 +18,7 @@ class Road {
this.cars = cars;
>this.cars = cars : Car[]
>this.cars : Car[]
>this : Road
>this : this
>cars : Car[]
>cars : Car[]
}
+2 -2
View File
@@ -38,12 +38,12 @@ class parser {
this.options = this.options.sort(function(a, b) {
>this.options = this.options.sort(function(a, b) { var aName = a.name.toLowerCase(); var bName = b.name.toLowerCase(); if (aName > bName) { return 1; } else if (aName < bName) { return -1; } else { return 0; } }) : IOptions[]
>this.options : IOptions[]
>this : parser
>this : this
>options : IOptions[]
>this.options.sort(function(a, b) { var aName = a.name.toLowerCase(); var bName = b.name.toLowerCase(); if (aName > bName) { return 1; } else if (aName < bName) { return -1; } else { return 0; } }) : IOptions[]
>this.options.sort : (compareFn?: (a: IOptions, b: IOptions) => number) => IOptions[]
>this.options : IOptions[]
>this : parser
>this : this
>options : IOptions[]
>sort : (compareFn?: (a: IOptions, b: IOptions) => number) => IOptions[]
>function(a, b) { var aName = a.name.toLowerCase(); var bName = b.name.toLowerCase(); if (aName > bName) { return 1; } else if (aName < bName) { return -1; } else { return 0; } } : (a: IOptions, b: IOptions) => number
@@ -129,12 +129,12 @@ class MyClass {
>1 : number
p = (n) => n && this;
>p : (n: any) => MyClass
>(n) => n && this : (n: any) => MyClass
>p : (n: any) => this
>(n) => n && this : (n: any) => this
>n : any
>n && this : MyClass
>n && this : this
>n : any
>this : MyClass
>this : this
fn() {
>fn : () => void
@@ -148,12 +148,12 @@ class MyClass {
>1 : number
var p = (n) => n && this;
>p : (n: any) => MyClass
>(n) => n && this : (n: any) => MyClass
>p : (n: any) => this
>(n) => n && this : (n: any) => this
>n : any
>n && this : MyClass
>n && this : this
>n : any
>this : MyClass
>this : this
}
}
+22
View File
@@ -0,0 +1,22 @@
//// [tests/cases/conformance/expressions/asOperator/asOperator4.ts] ////
//// [foo.ts]
export function foo() { }
//// [bar.ts]
import { foo } from './foo';
// These should emit identically
<any>foo;
(foo as any);
//// [foo.js]
function foo() { }
exports.foo = foo;
//// [bar.js]
var foo_1 = require('./foo');
// These should emit identically
foo_1.foo;
foo_1.foo;
@@ -0,0 +1,16 @@
=== tests/cases/conformance/expressions/asOperator/foo.ts ===
export function foo() { }
>foo : Symbol(foo, Decl(foo.ts, 0, 0))
=== tests/cases/conformance/expressions/asOperator/bar.ts ===
import { foo } from './foo';
>foo : Symbol(foo, Decl(bar.ts, 0, 8))
// These should emit identically
<any>foo;
>foo : Symbol(foo, Decl(bar.ts, 0, 8))
(foo as any);
>foo : Symbol(foo, Decl(bar.ts, 0, 8))
@@ -0,0 +1,19 @@
=== tests/cases/conformance/expressions/asOperator/foo.ts ===
export function foo() { }
>foo : () => void
=== tests/cases/conformance/expressions/asOperator/bar.ts ===
import { foo } from './foo';
>foo : () => void
// These should emit identically
<any>foo;
><any>foo : any
>foo : () => void
(foo as any);
>(foo as any) : any
>foo as any : any
>foo : () => void
@@ -0,0 +1,24 @@
tests/cases/compiler/asiAbstract.ts(1,1): error TS2304: Cannot find name 'abstract'.
tests/cases/compiler/asiAbstract.ts(3,3): error TS1244: Abstract methods can only appear within an abstract class.
==== tests/cases/compiler/asiAbstract.ts (2 errors) ====
abstract
~~~~~~~~
!!! error TS2304: Cannot find name 'abstract'.
class NonAbstractClass {
abstract s();
~~~~~~~~
!!! error TS1244: Abstract methods can only appear within an abstract class.
}
class C2 {
abstract
nonAbstractFunction() {
}
}
class C3 {
abstract
}
+36
View File
@@ -0,0 +1,36 @@
//// [asiAbstract.ts]
abstract
class NonAbstractClass {
abstract s();
}
class C2 {
abstract
nonAbstractFunction() {
}
}
class C3 {
abstract
}
//// [asiAbstract.js]
abstract;
var NonAbstractClass = (function () {
function NonAbstractClass() {
}
return NonAbstractClass;
})();
var C2 = (function () {
function C2() {
}
C2.prototype.nonAbstractFunction = function () {
};
return C2;
})();
var C3 = (function () {
function C3() {
}
return C3;
})();
@@ -0,0 +1,52 @@
tests/cases/compiler/asiPublicPrivateProtected.ts(1,1): error TS2304: Cannot find name 'public'.
tests/cases/compiler/asiPublicPrivateProtected.ts(12,1): error TS2304: Cannot find name 'private'.
tests/cases/compiler/asiPublicPrivateProtected.ts(23,1): error TS2304: Cannot find name 'protected'.
==== tests/cases/compiler/asiPublicPrivateProtected.ts (3 errors) ====
public
~~~~~~
!!! error TS2304: Cannot find name 'public'.
class NonPublicClass {
public s() {
}
}
class NonPublicClass2 {
public
private nonPublicFunction() {
}
}
private
~~~~~~~
!!! error TS2304: Cannot find name 'private'.
class NonPrivateClass {
private s() {
}
}
class NonPrivateClass2 {
private
public nonPrivateFunction() {
}
}
protected
~~~~~~~~~
!!! error TS2304: Cannot find name 'protected'.
class NonProtectedClass {
protected s() {
}
}
class NonProtectedClass2 {
protected
public nonProtectedFunction() {
}
}
class ClassWithThreeMembers {
public
private
protected
}
@@ -0,0 +1,93 @@
//// [asiPublicPrivateProtected.ts]
public
class NonPublicClass {
public s() {
}
}
class NonPublicClass2 {
public
private nonPublicFunction() {
}
}
private
class NonPrivateClass {
private s() {
}
}
class NonPrivateClass2 {
private
public nonPrivateFunction() {
}
}
protected
class NonProtectedClass {
protected s() {
}
}
class NonProtectedClass2 {
protected
public nonProtectedFunction() {
}
}
class ClassWithThreeMembers {
public
private
protected
}
//// [asiPublicPrivateProtected.js]
public;
var NonPublicClass = (function () {
function NonPublicClass() {
}
NonPublicClass.prototype.s = function () {
};
return NonPublicClass;
})();
var NonPublicClass2 = (function () {
function NonPublicClass2() {
}
NonPublicClass2.prototype.nonPublicFunction = function () {
};
return NonPublicClass2;
})();
private;
var NonPrivateClass = (function () {
function NonPrivateClass() {
}
NonPrivateClass.prototype.s = function () {
};
return NonPrivateClass;
})();
var NonPrivateClass2 = (function () {
function NonPrivateClass2() {
}
NonPrivateClass2.prototype.nonPrivateFunction = function () {
};
return NonPrivateClass2;
})();
protected;
var NonProtectedClass = (function () {
function NonProtectedClass() {
}
NonProtectedClass.prototype.s = function () {
};
return NonProtectedClass;
})();
var NonProtectedClass2 = (function () {
function NonProtectedClass2() {
}
NonProtectedClass2.prototype.nonProtectedFunction = function () {
};
return NonProtectedClass2;
})();
var ClassWithThreeMembers = (function () {
function ClassWithThreeMembers() {
}
return ClassWithThreeMembers;
})();
@@ -11,11 +11,12 @@ class C {
var fn = async () => await other.apply(this, arguments);
>fn : () => Promise<any>
>async () => await other.apply(this, arguments) : () => Promise<any>
>await other.apply(this, arguments) : any
>other.apply(this, arguments) : any
>other.apply : (thisArg: any, argArray?: any) => any
>other : () => void
>apply : (thisArg: any, argArray?: any) => any
>this : C
>this : this
>arguments : IArguments
}
}
@@ -6,9 +6,10 @@ class C {
>method : () => void
var fn = async () => await this;
>fn : () => Promise<C>
>async () => await this : () => Promise<C>
>this : C
>fn : () => Promise<this>
>async () => await this : () => Promise<this>
>await this : this
>this : this
}
}
@@ -13,6 +13,7 @@ async function func(): Promise<void> {
"before";
var b = await p || a;
>b : Symbol(b, Decl(awaitBinaryExpression1_es6.ts, 4, 7))
>p : Symbol(p, Decl(awaitBinaryExpression1_es6.ts, 1, 11))
>a : Symbol(a, Decl(awaitBinaryExpression1_es6.ts, 0, 11))
"after";
@@ -16,7 +16,8 @@ async function func(): Promise<void> {
var b = await p || a;
>b : boolean
>await p || a : boolean
>p : any
>await p : boolean
>p : Promise<boolean>
>a : boolean
"after";
@@ -13,6 +13,7 @@ async function func(): Promise<void> {
"before";
var b = await p && a;
>b : Symbol(b, Decl(awaitBinaryExpression2_es6.ts, 4, 7))
>p : Symbol(p, Decl(awaitBinaryExpression2_es6.ts, 1, 11))
>a : Symbol(a, Decl(awaitBinaryExpression2_es6.ts, 0, 11))
"after";
@@ -16,7 +16,8 @@ async function func(): Promise<void> {
var b = await p && a;
>b : boolean
>await p && a : boolean
>p : any
>await p : boolean
>p : Promise<boolean>
>a : boolean
"after";
@@ -13,6 +13,7 @@ async function func(): Promise<void> {
"before";
var b = await p + a;
>b : Symbol(b, Decl(awaitBinaryExpression3_es6.ts, 4, 7))
>p : Symbol(p, Decl(awaitBinaryExpression3_es6.ts, 1, 11))
>a : Symbol(a, Decl(awaitBinaryExpression3_es6.ts, 0, 11))
"after";
@@ -16,7 +16,8 @@ async function func(): Promise<void> {
var b = await p + a;
>b : number
>await p + a : number
>p : any
>await p : number
>p : Promise<number>
>a : number
"after";
@@ -13,6 +13,7 @@ async function func(): Promise<void> {
"before";
var b = await p, a;
>b : Symbol(b, Decl(awaitBinaryExpression4_es6.ts, 4, 7))
>p : Symbol(p, Decl(awaitBinaryExpression4_es6.ts, 1, 11))
>a : Symbol(a, Decl(awaitBinaryExpression4_es6.ts, 4, 20))
"after";
@@ -15,7 +15,8 @@ async function func(): Promise<void> {
var b = await p, a;
>b : boolean
>p : any
>await p : boolean
>p : Promise<boolean>
>a : any
"after";
@@ -19,6 +19,7 @@ async function func(): Promise<void> {
>o.a : Symbol(a, Decl(awaitBinaryExpression5_es6.ts, 4, 12))
>o : Symbol(o, Decl(awaitBinaryExpression5_es6.ts, 4, 7))
>a : Symbol(a, Decl(awaitBinaryExpression5_es6.ts, 4, 12))
>p : Symbol(p, Decl(awaitBinaryExpression5_es6.ts, 1, 11))
"after";
}
@@ -22,7 +22,8 @@ async function func(): Promise<void> {
>o.a : boolean
>o : { a: boolean; }
>a : boolean
>p : any
>await p : boolean
>p : Promise<boolean>
"after";
>"after" : string
@@ -42,6 +42,7 @@ async function func(): Promise<void> {
var b = fn(await p, a, a);
>b : Symbol(b, Decl(awaitCallExpression2_es6.ts, 8, 7))
>fn : Symbol(fn, Decl(awaitCallExpression2_es6.ts, 1, 32))
>p : Symbol(p, Decl(awaitCallExpression2_es6.ts, 1, 11))
>a : Symbol(a, Decl(awaitCallExpression2_es6.ts, 0, 11))
>a : Symbol(a, Decl(awaitCallExpression2_es6.ts, 0, 11))
@@ -45,7 +45,8 @@ async function func(): Promise<void> {
>b : void
>fn(await p, a, a) : void
>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void
>p : any
>await p : boolean
>p : Promise<boolean>
>a : boolean
>a : boolean
@@ -43,6 +43,7 @@ async function func(): Promise<void> {
>b : Symbol(b, Decl(awaitCallExpression3_es6.ts, 8, 7))
>fn : Symbol(fn, Decl(awaitCallExpression3_es6.ts, 1, 32))
>a : Symbol(a, Decl(awaitCallExpression3_es6.ts, 0, 11))
>p : Symbol(p, Decl(awaitCallExpression3_es6.ts, 1, 11))
>a : Symbol(a, Decl(awaitCallExpression3_es6.ts, 0, 11))
"after";
@@ -46,7 +46,8 @@ async function func(): Promise<void> {
>fn(a, await p, a) : void
>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void
>a : boolean
>p : any
>await p : boolean
>p : Promise<boolean>
>a : boolean
"after";
@@ -41,6 +41,7 @@ async function func(): Promise<void> {
"before";
var b = (await pfn)(a, a, a);
>b : Symbol(b, Decl(awaitCallExpression4_es6.ts, 8, 7))
>pfn : Symbol(pfn, Decl(awaitCallExpression4_es6.ts, 4, 11))
>a : Symbol(a, Decl(awaitCallExpression4_es6.ts, 0, 11))
>a : Symbol(a, Decl(awaitCallExpression4_es6.ts, 0, 11))
>a : Symbol(a, Decl(awaitCallExpression4_es6.ts, 0, 11))
@@ -45,7 +45,8 @@ async function func(): Promise<void> {
>b : void
>(await pfn)(a, a, a) : void
>(await pfn) : (arg0: boolean, arg1: boolean, arg2: boolean) => void
>pfn : any
>await pfn : (arg0: boolean, arg1: boolean, arg2: boolean) => void
>pfn : Promise<(arg0: boolean, arg1: boolean, arg2: boolean) => void>
>a : boolean
>a : boolean
>a : boolean
@@ -44,6 +44,7 @@ async function func(): Promise<void> {
>o.fn : Symbol(fn, Decl(awaitCallExpression6_es6.ts, 3, 16))
>o : Symbol(o, Decl(awaitCallExpression6_es6.ts, 3, 11))
>fn : Symbol(fn, Decl(awaitCallExpression6_es6.ts, 3, 16))
>p : Symbol(p, Decl(awaitCallExpression6_es6.ts, 1, 11))
>a : Symbol(a, Decl(awaitCallExpression6_es6.ts, 0, 11))
>a : Symbol(a, Decl(awaitCallExpression6_es6.ts, 0, 11))
@@ -47,7 +47,8 @@ async function func(): Promise<void> {
>o.fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void
>o : { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }
>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void
>p : any
>await p : boolean
>p : Promise<boolean>
>a : boolean
>a : boolean
@@ -45,6 +45,7 @@ async function func(): Promise<void> {
>o : Symbol(o, Decl(awaitCallExpression7_es6.ts, 3, 11))
>fn : Symbol(fn, Decl(awaitCallExpression7_es6.ts, 3, 16))
>a : Symbol(a, Decl(awaitCallExpression7_es6.ts, 0, 11))
>p : Symbol(p, Decl(awaitCallExpression7_es6.ts, 1, 11))
>a : Symbol(a, Decl(awaitCallExpression7_es6.ts, 0, 11))
"after";
@@ -48,7 +48,8 @@ async function func(): Promise<void> {
>o : { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }
>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void
>a : boolean
>p : any
>await p : boolean
>p : Promise<boolean>
>a : boolean
"after";
@@ -42,6 +42,7 @@ async function func(): Promise<void> {
var b = (await po).fn(a, a, a);
>b : Symbol(b, Decl(awaitCallExpression8_es6.ts, 8, 7))
>(await po).fn : Symbol(fn, Decl(awaitCallExpression8_es6.ts, 5, 25))
>po : Symbol(po, Decl(awaitCallExpression8_es6.ts, 5, 11))
>fn : Symbol(fn, Decl(awaitCallExpression8_es6.ts, 5, 25))
>a : Symbol(a, Decl(awaitCallExpression8_es6.ts, 0, 11))
>a : Symbol(a, Decl(awaitCallExpression8_es6.ts, 0, 11))
@@ -46,7 +46,8 @@ async function func(): Promise<void> {
>(await po).fn(a, a, a) : void
>(await po).fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void
>(await po) : { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }
>po : any
>await po : { fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }
>po : Promise<{ fn(arg0: boolean, arg1: boolean, arg2: boolean): void; }>
>fn : (arg0: boolean, arg1: boolean, arg2: boolean) => void
>a : boolean
>a : boolean
@@ -24,16 +24,21 @@ async function f() {
let await_a = await a;
>await_a : Symbol(await_a, Decl(awaitUnion_es6.ts, 6, 4))
>a : Symbol(a, Decl(awaitUnion_es6.ts, 0, 11))
let await_b = await b;
>await_b : Symbol(await_b, Decl(awaitUnion_es6.ts, 7, 4))
>b : Symbol(b, Decl(awaitUnion_es6.ts, 1, 11))
let await_c = await c;
>await_c : Symbol(await_c, Decl(awaitUnion_es6.ts, 8, 4))
>c : Symbol(c, Decl(awaitUnion_es6.ts, 2, 11))
let await_d = await d;
>await_d : Symbol(await_d, Decl(awaitUnion_es6.ts, 9, 4))
>d : Symbol(d, Decl(awaitUnion_es6.ts, 3, 11))
let await_e = await e;
>await_e : Symbol(await_e, Decl(awaitUnion_es6.ts, 10, 4))
>e : Symbol(e, Decl(awaitUnion_es6.ts, 4, 11))
}
+10 -5
View File
@@ -24,21 +24,26 @@ async function f() {
let await_a = await a;
>await_a : number | string
>a : any
>await a : number | string
>a : number | string
let await_b = await b;
>await_b : number | string
>b : any
>await b : number | string
>b : PromiseLike<number> | PromiseLike<string>
let await_c = await c;
>await_c : number | string
>c : any
>await c : number | string
>c : PromiseLike<number | string>
let await_d = await d;
>await_d : number | string
>d : any
>await d : number | string
>d : number | PromiseLike<string>
let await_e = await e;
>await_e : number | string
>e : any
>await e : number | string
>e : number | PromiseLike<number | string>
}
@@ -22,8 +22,8 @@ class Greeter {
>() => { var x = this; } : () => void
var x = this;
>x : Greeter
>this : Greeter
>x : this
>this : this
});
});

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