Merge branch 'master' into asyncFunctions

This commit is contained in:
Ron Buckton
2015-07-01 09:27:45 -07:00
1228 changed files with 34838 additions and 19373 deletions

View File

@@ -149,7 +149,7 @@ class CompilerBaselineRunner extends RunnerBase {
// check errors
it('Correct errors for ' + fileName, () => {
if (this.errors) {
Harness.Baseline.runBaseline('Correct errors for ' + fileName, justName.replace(/\.ts$/, '.errors.txt'), (): string => {
Harness.Baseline.runBaseline('Correct errors for ' + fileName, justName.replace(/\.tsx?$/, '.errors.txt'), (): string => {
if (result.errors.length === 0) return null;
return getErrorBaseline(toBeCompiled, otherFiles, result);
});
@@ -159,7 +159,7 @@ class CompilerBaselineRunner extends RunnerBase {
// Source maps?
it('Correct sourcemap content for ' + fileName, () => {
if (options.sourceMap || options.inlineSourceMap) {
Harness.Baseline.runBaseline('Correct sourcemap content for ' + fileName, justName.replace(/\.ts$/, '.sourcemap.txt'), () => {
Harness.Baseline.runBaseline('Correct sourcemap content for ' + fileName, justName.replace(/\.tsx?$/, '.sourcemap.txt'), () => {
var record = result.getSourceMapRecord();
if (options.noEmitOnError && result.errors.length !== 0 && record === undefined) {
// Because of the noEmitOnError option no files are created. We need to return null because baselining isn't required.
@@ -177,7 +177,7 @@ class CompilerBaselineRunner extends RunnerBase {
}
// check js output
Harness.Baseline.runBaseline('Correct JS output for ' + fileName, justName.replace(/\.ts/, '.js'), () => {
Harness.Baseline.runBaseline('Correct JS output for ' + fileName, justName.replace(/\.tsx?/, '.js'), () => {
var tsCode = '';
var tsSources = otherFiles.concat(toBeCompiled);
if (tsSources.length > 1) {
@@ -235,7 +235,7 @@ class CompilerBaselineRunner extends RunnerBase {
throw new Error('Number of sourcemap files should be same as js files.');
}
Harness.Baseline.runBaseline('Correct Sourcemap output for ' + fileName, justName.replace(/\.ts/, '.js.map'), () => {
Harness.Baseline.runBaseline('Correct Sourcemap output for ' + fileName, justName.replace(/\.tsx?/, '.js.map'), () => {
if (options.noEmitOnError && result.errors.length !== 0 && result.sourceMaps.length === 0) {
// We need to return null here or the runBaseLine will actually create a empty file.
// Baselining isn't required here because there is no output.
@@ -320,11 +320,11 @@ class CompilerBaselineRunner extends RunnerBase {
let pullExtension = isSymbolBaseLine ? '.symbols.pull' : '.types.pull';
if (fullBaseLine !== pullBaseLine) {
Harness.Baseline.runBaseline('Correct full information for ' + fileName, justName.replace(/\.ts/, fullExtension), () => fullBaseLine);
Harness.Baseline.runBaseline('Correct pull information for ' + fileName, justName.replace(/\.ts/, pullExtension), () => pullBaseLine);
Harness.Baseline.runBaseline('Correct full information for ' + fileName, justName.replace(/\.tsx?/, fullExtension), () => fullBaseLine);
Harness.Baseline.runBaseline('Correct pull information for ' + fileName, justName.replace(/\.tsx?/, pullExtension), () => pullBaseLine);
}
else {
Harness.Baseline.runBaseline('Correct information for ' + fileName, justName.replace(/\.ts/, fullExtension), () => fullBaseLine);
Harness.Baseline.runBaseline('Correct information for ' + fileName, justName.replace(/\.tsx?/, fullExtension), () => fullBaseLine);
}
}
@@ -391,7 +391,7 @@ class CompilerBaselineRunner extends RunnerBase {
// this will set up a series of describe/it blocks to run between the setup and cleanup phases
if (this.tests.length === 0) {
var testFiles = this.enumerateFiles(this.basePath, /\.ts$/, { recursive: true });
var testFiles = this.enumerateFiles(this.basePath, /\.tsx?$/, { recursive: true });
testFiles.forEach(fn => {
fn = fn.replace(/\\/g, "/");
this.checkTestCodeOutput(fn);

View File

@@ -660,8 +660,7 @@ module FourSlash {
}
errorMsg += "]\n";
Harness.IO.log(errorMsg);
this.raiseError("Member list is not empty at Caret");
this.raiseError("Member list is not empty at Caret: " + errorMsg);
}
}
@@ -744,7 +743,7 @@ module FourSlash {
var reference = references[i];
if (reference && reference.fileName === fileName && reference.textSpan.start === start && ts.textSpanEnd(reference.textSpan) === end) {
if (typeof isWriteAccess !== "undefined" && reference.isWriteAccess !== isWriteAccess) {
this.raiseError('verifyReferencesAtPositionListContains failed - item isWriteAccess value doe not match, actual: ' + reference.isWriteAccess + ', expected: ' + isWriteAccess + '.');
this.raiseError('verifyReferencesAtPositionListContains failed - item isWriteAccess value does not match, actual: ' + reference.isWriteAccess + ', expected: ' + isWriteAccess + '.');
}
return;
}
@@ -831,6 +830,7 @@ module FourSlash {
if (expectedText !== undefined) {
assert.notEqual(actualQuickInfoText, expectedText, this.messageAtLastKnownMarker("quick info text"));
}
// TODO: should be '==='?
if (expectedDocumentation != undefined) {
assert.notEqual(actualQuickInfoDocumentation, expectedDocumentation, this.messageAtLastKnownMarker("quick info doc comment"));
}
@@ -838,6 +838,7 @@ module FourSlash {
if (expectedText !== undefined) {
assert.equal(actualQuickInfoText, expectedText, this.messageAtLastKnownMarker("quick info text"));
}
// TODO: should be '==='?
if (expectedDocumentation != undefined) {
assert.equal(actualQuickInfoDocumentation, expectedDocumentation, assertionMessage("quick info doc"));
}
@@ -883,8 +884,16 @@ module FourSlash {
this.activeFile.fileName, this.currentCaretPosition, findInStrings, findInComments);
var ranges = this.getRanges();
if (!references) {
if (ranges.length !== 0) {
this.raiseError(`Expected ${ranges.length} rename locations; got none.`);
}
return;
}
if (ranges.length !== references.length) {
this.raiseError(this.assertionMessage("Rename locations", references.length, ranges.length));
this.raiseError("Rename location count does not match result.\n\nExpected: " + JSON.stringify(ranges) + "\n\nActual:" + JSON.stringify(references));
}
ranges = ranges.sort((r1, r2) => r1.start - r2.start);
@@ -897,9 +906,7 @@ module FourSlash {
if (reference.textSpan.start !== range.start ||
ts.textSpanEnd(reference.textSpan) !== range.end) {
this.raiseError(this.assertionMessage("Rename location",
"[" + reference.textSpan.start + "," + ts.textSpanEnd(reference.textSpan) + ")",
"[" + range.start + "," + range.end + ")"));
this.raiseError("Rename location results do not match.\n\nExpected: " + JSON.stringify(ranges) + "\n\nActual:" + JSON.stringify(references));
}
}
}
@@ -1820,7 +1827,7 @@ module FourSlash {
}
private verifyProjectInfo(expected: string[]) {
if (this.testType == FourSlashTestType.Server) {
if (this.testType === FourSlashTestType.Server) {
let actual = (<ts.server.SessionClient>this.languageService).getProjectInfo(
this.activeFile.fileName,
/* needFileNameList */ true
@@ -1937,7 +1944,7 @@ module FourSlash {
}
}
if (expected != actual) {
if (expected !== actual) {
this.raiseError('verifyNavigationItemsCount failed - found: ' + actual + ' navigation items, expected: ' + expected + '.');
}
}
@@ -1984,7 +1991,7 @@ module FourSlash {
var items = this.languageService.getNavigationBarItems(this.activeFile.fileName);
var actual = this.getNavigationBarItemsCount(items);
if (expected != actual) {
if (expected !== actual) {
this.raiseError('verifyGetScriptLexicalStructureListCount failed - found: ' + actual + ' navigation items, expected: ' + expected + '.');
}
}
@@ -2402,6 +2409,7 @@ module FourSlash {
globalOptions[match[1]] = match[2];
}
}
// TODO: should be '==='?
} 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

View File

@@ -212,7 +212,7 @@ module Utils {
}
var result = "";
ts.forEach(Object.getOwnPropertyNames(flags),(v: any) => {
ts.forEach(Object.getOwnPropertyNames(flags), (v: any) => {
if (isFinite(v)) {
v = +v;
if (f === +v) {
@@ -410,7 +410,7 @@ module Harness {
deleteFile(fileName: string): void;
listFiles(path: string, filter: RegExp, options?: { recursive?: boolean }): string[];
log(text: string): void;
getMemoryUsage? (): number;
getMemoryUsage?(): number;
}
module IOImpl {
@@ -794,7 +794,7 @@ module Harness {
public reset() { this.fileCollection = {}; }
public toArray(): { fileName: string; file: WriterAggregator; }[]{
public toArray(): { fileName: string; file: WriterAggregator; }[] {
var result: { fileName: string; file: WriterAggregator; }[] = [];
for (var p in this.fileCollection) {
if (this.fileCollection.hasOwnProperty(p)) {
@@ -1170,6 +1170,12 @@ module Harness {
options.inlineSources = setting.value === 'true';
break;
case 'jsx':
options.jsx = setting.value.toLowerCase() === 'react' ? ts.JsxEmit.React :
setting.value.toLowerCase() === 'preserve' ? ts.JsxEmit.Preserve :
ts.JsxEmit.None;
break;
default:
throw new Error('Unsupported compiler setting ' + setting.flag);
}
@@ -1233,7 +1239,7 @@ module Harness {
}
var dTsFileName = ts.removeFileExtension(sourceFileName) + ".d.ts";
return ts.forEach(result.declFilesCode, declFile => declFile.fileName === dTsFileName ? declFile : undefined);
}
@@ -1432,6 +1438,10 @@ module Harness {
return stringEndsWith(fileName, '.ts');
}
export function isTSX(fileName: string) {
return stringEndsWith(fileName, '.tsx');
}
export function isDTS(fileName: string) {
return stringEndsWith(fileName, '.d.ts');
}
@@ -1439,6 +1449,9 @@ module Harness {
export function isJS(fileName: string) {
return stringEndsWith(fileName, '.js');
}
export function isJSX(fileName: string) {
return stringEndsWith(fileName, '.jsx');
}
export function isJSMap(fileName: string) {
return stringEndsWith(fileName, '.js.map');
@@ -1459,12 +1472,15 @@ module Harness {
if (isDTS(emittedFile.fileName)) {
// .d.ts file, add to declFiles emit
this.declFilesCode.push(emittedFile);
} else if (isJS(emittedFile.fileName)) {
}
else if (isJS(emittedFile.fileName) || isJSX(emittedFile.fileName)) {
// .js file, add to files
this.files.push(emittedFile);
} else if (isJSMap(emittedFile.fileName)) {
}
else if (isJSMap(emittedFile.fileName)) {
this.sourceMaps.push(emittedFile);
} else {
}
else {
throw new Error('Unrecognized file extension for file ' + emittedFile.fileName);
}
});
@@ -1499,6 +1515,16 @@ module Harness {
// Regex for parsing options in the format "@Alpha: Value of any sort"
var optionRegex = /^[\/]{2}\s*@(\w+)\s*:\s*(\S*)/gm; // multiple matches on multiple lines
// List of allowed metadata names
var fileMetadataNames = ["filename", "comments", "declaration", "module",
"nolib", "sourcemap", "target", "out", "outdir", "noemithelpers", "noemitonerror",
"noimplicitany", "noresolve", "newline", "normalizenewline", "emitbom",
"errortruncation", "usecasesensitivefilenames", "preserveconstenums",
"includebuiltfile", "suppressimplicitanyindexerrors", "stripinternal",
"isolatedmodules", "inlinesourcemap", "maproot", "sourceroot",
"inlinesources", "emitdecoratormetadata", "experimentaldecorators",
"skipdefaultlibcheck", "jsx"];
function extractCompilerSettings(content: string): CompilerSetting[] {
var opts: CompilerSetting[] = [];

View File

@@ -583,7 +583,7 @@ module Harness.LanguageService {
// This host is just a proxy for the clientHost, it uses the client
// host to answer server queries about files on disk
var serverHost = new SessionServerHost(clientHost);
var server = new ts.server.Session(serverHost, serverHost);
var server = new ts.server.Session(serverHost, Buffer.byteLength, process.hrtime, serverHost);
// Fake the connection between the client and the server
serverHost.writeMessage = client.onMessage.bind(client);

View File

@@ -110,6 +110,7 @@ class ProjectRunner extends RunnerBase {
else if (url.indexOf(diskProjectPath) === 0) {
// Replace the disk specific path into the project root path
url = url.substr(diskProjectPath.length);
// TODO: should be '!=='?
if (url.charCodeAt(0) != ts.CharacterCodes.slash) {
url = "/" + url;
}
@@ -240,7 +241,7 @@ class ProjectRunner extends RunnerBase {
if (Harness.Compiler.isJS(fileName)) {
// Make sure if there is URl we have it cleaned up
var indexOfSourceMapUrl = data.lastIndexOf("//# sourceMappingURL=");
if (indexOfSourceMapUrl != -1) {
if (indexOfSourceMapUrl !== -1) {
data = data.substring(0, indexOfSourceMapUrl + 21) + cleanProjectUrl(data.substring(indexOfSourceMapUrl + 21));
}
}

View File

@@ -27,7 +27,7 @@ class RunnerBase {
var fixedPath = path;
// full paths either start with a drive letter or / for *nix, shouldn't have \ in the path at this point
var fullPath = /(\w+:|\/)?([\w+\-\.]|\/)*\.ts/g;
var fullPath = /(\w+:|\/)?([\w+\-\.]|\/)*\.tsx?/g;
var fullPathList = fixedPath.match(fullPath);
if (fullPathList) {
fullPathList.forEach((match: string) => fixedPath = fixedPath.replace(match, Harness.Path.getFileName(match)));

View File

@@ -46,7 +46,7 @@ module Harness.SourceMapRecoder {
}
function isSourceMappingSegmentEnd() {
if (decodingIndex == sourceMapMappings.length) {
if (decodingIndex === sourceMapMappings.length) {
return true;
}
@@ -95,7 +95,7 @@ module Harness.SourceMapRecoder {
var currentByte = base64FormatDecode();
// If msb is set, we still have more bits to continue
moreDigits = (currentByte & 32) != 0;
moreDigits = (currentByte & 32) !== 0;
// least significant 5 bits are the next msbs in the final value.
value = value | ((currentByte & 31) << shiftCount);
@@ -103,7 +103,7 @@ module Harness.SourceMapRecoder {
}
// Least significant bit if 1 represents negative and rest of the msb is actual absolute value
if ((value & 1) == 0) {
if ((value & 1) === 0) {
// + number
value = value >> 1;
}
@@ -182,7 +182,7 @@ module Harness.SourceMapRecoder {
}
}
// Dont support reading mappings that dont have information about original source and its line numbers
if (createErrorIfCondition(!isSourceMappingSegmentEnd(), "Unsupported Error Format: There are more entries after " + (decodeOfEncodedMapping.nameIndex == -1 ? "sourceColumn" : "nameIndex"))) {
if (createErrorIfCondition(!isSourceMappingSegmentEnd(), "Unsupported Error Format: There are more entries after " + (decodeOfEncodedMapping.nameIndex === -1 ? "sourceColumn" : "nameIndex"))) {
return { error: errorDecodeOfEncodedMapping, sourceMapSpan: decodeOfEncodedMapping };
}
@@ -249,7 +249,7 @@ module Harness.SourceMapRecoder {
mapString += " name (" + sourceMapNames[mapEntry.nameIndex] + ")";
}
else {
if (mapEntry.nameIndex != -1 || getAbsentNameIndex) {
if (mapEntry.nameIndex !== -1 || getAbsentNameIndex) {
mapString += " nameIndex (" + mapEntry.nameIndex + ")";
}
}
@@ -262,12 +262,12 @@ module Harness.SourceMapRecoder {
var decodeResult = SourceMapDecoder.decodeNextEncodedSourceMapSpan();
var decodedErrors: string[];
if (decodeResult.error
|| decodeResult.sourceMapSpan.emittedLine != sourceMapSpan.emittedLine
|| decodeResult.sourceMapSpan.emittedColumn != sourceMapSpan.emittedColumn
|| decodeResult.sourceMapSpan.sourceLine != sourceMapSpan.sourceLine
|| decodeResult.sourceMapSpan.sourceColumn != sourceMapSpan.sourceColumn
|| decodeResult.sourceMapSpan.sourceIndex != sourceMapSpan.sourceIndex
|| decodeResult.sourceMapSpan.nameIndex != sourceMapSpan.nameIndex) {
|| decodeResult.sourceMapSpan.emittedLine !== sourceMapSpan.emittedLine
|| decodeResult.sourceMapSpan.emittedColumn !== sourceMapSpan.emittedColumn
|| decodeResult.sourceMapSpan.sourceLine !== sourceMapSpan.sourceLine
|| decodeResult.sourceMapSpan.sourceColumn !== sourceMapSpan.sourceColumn
|| decodeResult.sourceMapSpan.sourceIndex !== sourceMapSpan.sourceIndex
|| decodeResult.sourceMapSpan.nameIndex !== sourceMapSpan.nameIndex) {
if (decodeResult.error) {
decodedErrors = ["!!^^ !!^^ There was decoding error in the sourcemap at this location: " + decodeResult.error];
}
@@ -288,7 +288,7 @@ module Harness.SourceMapRecoder {
}
export function recordNewSourceFileSpan(sourceMapSpan: ts.SourceMapSpan, newSourceFileCode: string) {
assert.isTrue(spansOnSingleLine.length == 0 || spansOnSingleLine[0].sourceMapSpan.emittedLine !== sourceMapSpan.emittedLine, "new file source map span should be on new line. We currently handle only that scenario");
assert.isTrue(spansOnSingleLine.length === 0 || spansOnSingleLine[0].sourceMapSpan.emittedLine !== sourceMapSpan.emittedLine, "new file source map span should be on new line. We currently handle only that scenario");
recordSourceMapSpan(sourceMapSpan);
assert.isTrue(spansOnSingleLine.length === 1);
@@ -395,9 +395,9 @@ module Harness.SourceMapRecoder {
var tsCodeLineMap = ts.computeLineStarts(sourceText);
for (var i = 0; i < tsCodeLineMap.length; i++) {
writeSourceMapIndent(prevEmittedCol, i == 0 ? markerIds[index] : " >");
writeSourceMapIndent(prevEmittedCol, i === 0 ? markerIds[index] : " >");
sourceMapRecoder.Write(getTextOfLine(i, tsCodeLineMap, sourceText));
if (i == tsCodeLineMap.length - 1) {
if (i === tsCodeLineMap.length - 1) {
sourceMapRecoder.WriteLine("");
}
}
@@ -447,7 +447,7 @@ module Harness.SourceMapRecoder {
for (var j = 0; j < sourceMapData.sourceMapDecodedMappings.length; j++) {
var decodedSourceMapping = sourceMapData.sourceMapDecodedMappings[j];
var currentSourceFile = program.getSourceFile(sourceMapData.inputSourceFileNames[decodedSourceMapping.sourceIndex]);
if (currentSourceFile != prevSourceFile) {
if (currentSourceFile !== prevSourceFile) {
SourceMapSpanWriter.recordNewSourceFileSpan(decodedSourceMapping, currentSourceFile.text);
prevSourceFile = currentSourceFile;
}

View File

@@ -41,7 +41,10 @@ class TypeWriterWalker {
var lineAndCharacter = this.currentSourceFile.getLineAndCharacterOfPosition(actualPos);
var sourceText = ts.getTextOfNodeFromSourceText(this.currentSourceFile.text, node);
var type = this.checker.getTypeAtLocation(node);
// Workaround to ensure we output 'C' instead of 'typeof C' for base class expressions
// var type = this.checker.getTypeAtLocation(node);
var type = node.parent && ts.isExpressionWithTypeArgumentsInClassExtendsClause(node.parent) && this.checker.getTypeAtLocation(node.parent) || this.checker.getTypeAtLocation(node);
ts.Debug.assert(type !== undefined, "type doesn't exist");
var symbol = this.checker.getSymbolAtLocation(node);