Merge branch 'master' into funcDeclsInBlocks

This commit is contained in:
Cyrus Najmabadi
2014-12-15 20:50:48 -08:00
42 changed files with 220 additions and 343 deletions

View File

@@ -485,7 +485,7 @@ function deleteTemporaryProjectOutput() {
}
}
var testTimeout = 5000;
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>]'.");
task("runtests", ["tests", builtLocalDirectory], function() {
cleanTestDirs();

View File

@@ -227,23 +227,27 @@ module ts {
if (symbolKind & SymbolFlags.HasLocals) {
node.locals = {};
}
var saveParent = parent;
var saveContainer = container;
var savedBlockScopeContainer = blockScopeContainer;
parent = node;
if (symbolKind & SymbolFlags.IsContainer) {
container = node;
// If container is not on container list, add it to the list
if (lastContainer !== container && !container.nextContainer) {
if (lastContainer) {
lastContainer.nextContainer = container;
}
lastContainer = container;
Debug.assert(container.nextContainer === undefined);
if (lastContainer) {
Debug.assert(lastContainer.nextContainer === undefined);
lastContainer.nextContainer = container;
}
lastContainer = container;
}
if (isBlockScopeContainer) {
blockScopeContainer = node;
}
forEachChild(node, bind);
container = saveContainer;
parent = saveParent;
@@ -292,15 +296,6 @@ module ts {
bindChildren(node, symbolKind, isBlockScopeContainer);
}
function bindConstructorDeclaration(node: ConstructorDeclaration) {
bindDeclaration(node, SymbolFlags.Constructor, 0, /*isBlockScopeContainer*/ true);
forEach(node.parameters, p => {
if (p.flags & (NodeFlags.Public | NodeFlags.Private | NodeFlags.Protected)) {
bindDeclaration(p, SymbolFlags.Property, SymbolFlags.PropertyExcludes, /*isBlockScopeContainer*/ false);
}
});
}
function bindModuleDeclaration(node: ModuleDeclaration) {
if (node.name.kind === SyntaxKind.StringLiteral) {
bindDeclaration(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes, /*isBlockScopeContainer*/ true);
@@ -389,12 +384,7 @@ module ts {
bindDeclaration(<Declaration>node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes, /*isBlockScopeContainer*/ false);
break;
case SyntaxKind.Parameter:
if (isBindingPattern((<Declaration>node).name)) {
bindAnonymousDeclaration(<Declaration>node, SymbolFlags.FunctionScopedVariable, getDestructuringParameterName(<Declaration>node), /*isBlockScopeContainer*/ false);
}
else {
bindDeclaration(<Declaration>node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes, /*isBlockScopeContainer*/ false);
}
bindParameter(<ParameterDeclaration>node);
break;
case SyntaxKind.VariableDeclaration:
case SyntaxKind.BindingElement:
@@ -437,7 +427,7 @@ module ts {
bindDeclaration(<Declaration>node, SymbolFlags.Function, SymbolFlags.FunctionExcludes, /*isBlockScopeContainer*/ true);
break;
case SyntaxKind.Constructor:
bindConstructorDeclaration(<ConstructorDeclaration>node);
bindDeclaration(<Declaration>node, SymbolFlags.Constructor, /*symbolExcludes:*/ 0, /*isBlockScopeContainer:*/ true);
break;
case SyntaxKind.GetAccessor:
bindDeclaration(<Declaration>node, SymbolFlags.GetAccessor, SymbolFlags.GetAccessorExcludes, /*isBlockScopeContainer*/ true);
@@ -506,5 +496,24 @@ module ts {
parent = saveParent;
}
}
function bindParameter(node: ParameterDeclaration) {
if (isBindingPattern(node.name)) {
bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, getDestructuringParameterName(node), /*isBlockScopeContainer*/ false);
}
else {
bindDeclaration(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes, /*isBlockScopeContainer*/ false);
}
// If this is a property-parameter, then also declare the property symbol into the
// containing class.
if (node.flags & NodeFlags.AccessibilityModifier &&
node.parent.kind === SyntaxKind.Constructor &&
node.parent.parent.kind === SyntaxKind.ClassDeclaration) {
var classDeclaration = <ClassDeclaration>node.parent.parent;
declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes);
}
}
}
}

View File

@@ -323,14 +323,12 @@ module ts {
// Context flags computed by aggregating child flags upwards.
// If this node, or any of it's children (transitively) contain an error.
// Used during incremental parsing to determine if this node or any of its children had an
// error. Computed only once and then cached.
ThisNodeOrAnySubNodesHasError = 1 << 5,
// Used during incremental parsing to determine if we need to visit this node to see if
// any of its children had an error. Once we compute that once, we can set this bit on the
// node to know that we never have to do it again. From that point on, we can just check
// the node directly for 'ContainsError'.
HasComputedThisNodeOrAnySubNodesHasError = 1 << 6
// Used to know if we've computed data from children and cached it in this node.
HasAggregatedChildData = 1 << 6
}
export interface Node extends TextRange {

View File

@@ -62,31 +62,34 @@ module ts {
return node.end - node.pos;
}
export function hasFlag(val: number, flag: number): boolean {
function hasFlag(val: number, flag: number): boolean {
return (val & flag) !== 0;
}
// Returns true if this node contains a parse error anywhere underneath it.
export function containsParseError(node: Node): boolean {
if (!hasFlag(node.parserContextFlags, ParserContextFlags.HasComputedThisNodeOrAnySubNodesHasError)) {
aggregateChildData(node);
return hasFlag(node.parserContextFlags, ParserContextFlags.ThisNodeOrAnySubNodesHasError);
}
function aggregateChildData(node: Node): void {
if (!hasFlag(node.parserContextFlags, ParserContextFlags.HasAggregatedChildData)) {
// A node is considered to contain a parse error if:
// a) the parser explicitly marked that it had an error
// b) any of it's children reported that it had an error.
var val = hasFlag(node.parserContextFlags, ParserContextFlags.ThisNodeHasError) ||
var thisNodeOrAnySubNodesHasError = hasFlag(node.parserContextFlags, ParserContextFlags.ThisNodeHasError) ||
forEachChild(node, containsParseError);
// If so, mark ourselves accordingly.
if (val) {
if (thisNodeOrAnySubNodesHasError) {
node.parserContextFlags |= ParserContextFlags.ThisNodeOrAnySubNodesHasError;
}
// Also mark that we've propogated the child information to this node. This way we can
// always consult the bit directly on this node without needing to check its children
// again.
node.parserContextFlags |= ParserContextFlags.HasComputedThisNodeOrAnySubNodesHasError;
node.parserContextFlags |= ParserContextFlags.HasAggregatedChildData;
}
return hasFlag(node.parserContextFlags, ParserContextFlags.ThisNodeOrAnySubNodesHasError);
}
export function getSourceFileOfNode(node: Node): SourceFile {

View File

@@ -96,19 +96,6 @@ module FourSlash {
end: number;
}
export enum IncrementalEditValidation {
None,
SyntacticOnly,
Complete
}
export enum TypingFidelity {
/// Performs typing and formatting (if formatting is enabled)
Low,
/// Performs typing, checks completion lists, signature help, and formatting (if enabled)
High
}
var entityMap: ts.Map<string> = {
'&': '&amp;',
'"': '&quot;',
@@ -126,22 +113,22 @@ module FourSlash {
// To add additional option, add property into the testOptMetadataNames, refer the property in either globalMetadataNames or fileMetadataNames
// Add cases into convertGlobalOptionsToCompilationsSettings function for the compiler to acknowledge such option from meta data
var testOptMetadataNames = {
baselineFile: 'BaselineFile',
declaration: 'declaration',
emitThisFile: 'emitThisFile', // This flag is used for testing getEmitOutput feature. It allows test-cases to indicate what file to be output in multiple files project
filename: 'Filename',
mapRoot: 'mapRoot',
module: 'module',
out: 'out',
outDir: 'outDir',
sourceMap: 'sourceMap',
sourceRoot: 'sourceRoot',
resolveReference: 'ResolveReference', // This flag is used to specify entry file for resolve file references. The flag is only allow once per test file
baselineFile: 'BaselineFile',
declaration: 'declaration',
emitThisFile: 'emitThisFile', // This flag is used for testing getEmitOutput feature. It allows test-cases to indicate what file to be output in multiple files project
filename: 'Filename',
mapRoot: 'mapRoot',
module: 'module',
out: 'out',
outDir: 'outDir',
sourceMap: 'sourceMap',
sourceRoot: 'sourceRoot',
resolveReference: 'ResolveReference', // This flag is used to specify entry file for resolve file references. The flag is only allow once per test file
};
// List of allowed metadata names
var fileMetadataNames = [testOptMetadataNames.filename, testOptMetadataNames.emitThisFile, testOptMetadataNames.resolveReference];
var globalMetadataNames = [testOptMetadataNames.baselineFile, testOptMetadataNames.declaration,
var globalMetadataNames = [testOptMetadataNames.baselineFile, testOptMetadataNames.declaration,
testOptMetadataNames.mapRoot, testOptMetadataNames.module, testOptMetadataNames.out,
testOptMetadataNames.outDir, testOptMetadataNames.sourceMap, testOptMetadataNames.sourceRoot]
@@ -160,16 +147,16 @@ module FourSlash {
case testOptMetadataNames.module:
// create appropriate external module target for CompilationSettings
switch (globalOptions[prop]) {
case "AMD":
settings.module = ts.ModuleKind.AMD;
break;
case "CommonJS":
settings.module = ts.ModuleKind.CommonJS;
break;
default:
ts.Debug.assert(globalOptions[prop] === undefined || globalOptions[prop] === "None");
settings.module = ts.ModuleKind.None;
break;
case "AMD":
settings.module = ts.ModuleKind.AMD;
break;
case "CommonJS":
settings.module = ts.ModuleKind.CommonJS;
break;
default:
ts.Debug.assert(globalOptions[prop] === undefined || globalOptions[prop] === "None");
settings.module = ts.ModuleKind.None;
break;
}
break;
case testOptMetadataNames.out:
@@ -279,9 +266,6 @@ module FourSlash {
public cancellationToken: TestCancellationToken;
public editValidation = IncrementalEditValidation.Complete;
public typingFidelity = TypingFidelity.Low;
private scenarioActions: string[] = [];
private taoInvalidReason: string = null;
@@ -771,7 +755,7 @@ module FourSlash {
}
public verifyQuickInfoString(negative: boolean, expectedText?: string, expectedDocumentation?: string) {
[expectedText, expectedDocumentation].forEach(str => {
[expectedText, expectedDocumentation].forEach(str => {
if (str) {
this.scenarioActions.push('<ShowQuickInfo />');
this.scenarioActions.push('<VerifyQuickInfoTextContains IgnoreSpacing="true" Text="' + escapeXmlAttributeValue(str) + '" ' + (negative ? 'ExpectsFailure="true"' : '') + ' />');
@@ -816,7 +800,7 @@ module FourSlash {
result = "[\n ";
}
result += JSON.stringify(part);
});
});
if (result) {
result += "\n]";
}
@@ -885,8 +869,8 @@ module FourSlash {
var help = this.getActiveSignatureHelpItem();
assert.equal(
ts.displayPartsToString(help.prefixDisplayParts) +
help.parameters.map(p => ts.displayPartsToString(p.displayParts)).join(ts.displayPartsToString(help.separatorDisplayParts)) +
ts.displayPartsToString(help.prefixDisplayParts) +
help.parameters.map(p => ts.displayPartsToString(p.displayParts)).join(ts.displayPartsToString(help.separatorDisplayParts)) +
ts.displayPartsToString(help.suffixDisplayParts), expected);
}
@@ -1233,11 +1217,6 @@ module FourSlash {
ts.forEach(fileNames, Harness.IO.log);
}
private editCheckpoint(filename: string) {
// TODO: What's this for? It is being called by deleteChar
// this.languageService.getScriptLexicalStructure(filename);
}
public deleteChar(count = 1) {
this.scenarioActions.push('<DeleteCharNext Count="' + count + '" />');
@@ -1248,7 +1227,7 @@ module FourSlash {
// Make the edit
this.languageServiceShimHost.editScript(this.activeFile.fileName, offset, offset + 1, ch);
this.updateMarkersForEdit(this.activeFile.fileName, offset, offset + 1, ch);
this.editCheckpoint(this.activeFile.fileName);
this.checkPostEditInvariants();
// Handle post-keystroke formatting
if (this.enableFormatting) {
@@ -1269,7 +1248,7 @@ module FourSlash {
this.languageServiceShimHost.editScript(this.activeFile.fileName, start, start + length, text);
this.updateMarkersForEdit(this.activeFile.fileName, start, start + length, text);
this.editCheckpoint(this.activeFile.fileName);
this.checkPostEditInvariants();
this.checkPostEditInvariants();
}
@@ -1285,13 +1264,13 @@ module FourSlash {
// Make the edit
this.languageServiceShimHost.editScript(this.activeFile.fileName, offset, offset + 1, ch);
this.updateMarkersForEdit(this.activeFile.fileName, offset, offset + 1, ch);
this.editCheckpoint(this.activeFile.fileName);
this.checkPostEditInvariants();
// Handle post-keystroke formatting
if (this.enableFormatting) {
var edits = this.languageService.getFormattingEditsAfterKeystroke(this.activeFile.fileName, offset, ch, this.formatCodeOptions);
offset += this.applyEdits(this.activeFile.fileName, edits, true);
this.editCheckpoint(this.activeFile.fileName);
this.checkPostEditInvariants();
}
}
@@ -1299,7 +1278,6 @@ module FourSlash {
this.currentCaretPosition = offset;
this.fixCaretPosition();
this.checkPostEditInvariants();
}
@@ -1311,37 +1289,7 @@ module FourSlash {
this.scenarioActions.push('<InsertText><![CDATA[' + text + ']]></InsertText>');
}
if (this.typingFidelity === TypingFidelity.Low) {
return this.typeLowFidelity(text);
} else {
return this.typeHighFidelity(text);
}
}
private typeLowFidelity(text: string) {
var offset = this.currentCaretPosition;
for (var i = 0; i < text.length; i++) {
// Make the edit
var ch = text.charAt(i);
this.languageServiceShimHost.editScript(this.activeFile.fileName, offset, offset, ch);
this.updateMarkersForEdit(this.activeFile.fileName, offset, offset, ch);
this.editCheckpoint(this.activeFile.fileName);
offset++;
// Handle post-keystroke formatting
if (this.enableFormatting) {
var edits = this.languageService.getFormattingEditsAfterKeystroke(this.activeFile.fileName, offset, ch, this.formatCodeOptions);
offset += this.applyEdits(this.activeFile.fileName, edits, true);
this.editCheckpoint(this.activeFile.fileName);
}
}
// Move the caret to wherever we ended up
this.currentCaretPosition = offset;
this.fixCaretPosition();
this.checkPostEditInvariants();
return this.typeHighFidelity(text);
}
// Enters lines of text at the current caret position, invoking
@@ -1357,7 +1305,7 @@ module FourSlash {
this.languageService.getBraceMatchingAtPosition(this.activeFile.fileName, offset);
this.updateMarkersForEdit(this.activeFile.fileName, offset, offset, ch);
this.editCheckpoint(this.activeFile.fileName);
this.checkPostEditInvariants();
offset++;
if (ch === '(' || ch === ',') {
@@ -1377,7 +1325,7 @@ module FourSlash {
if (this.enableFormatting) {
var edits = this.languageService.getFormattingEditsAfterKeystroke(this.activeFile.fileName, offset, ch, this.formatCodeOptions);
offset += this.applyEdits(this.activeFile.fileName, edits, true);
this.editCheckpoint(this.activeFile.fileName);
this.checkPostEditInvariants();
}
}
@@ -1385,7 +1333,6 @@ module FourSlash {
this.currentCaretPosition = offset;
this.fixCaretPosition();
this.checkPostEditInvariants();
}
@@ -1397,14 +1344,14 @@ module FourSlash {
var offset = this.currentCaretPosition;
this.languageServiceShimHost.editScript(this.activeFile.fileName, offset, offset, text);
this.updateMarkersForEdit(this.activeFile.fileName, offset, offset, text);
this.editCheckpoint(this.activeFile.fileName);
this.checkPostEditInvariants();
offset += text.length;
// Handle formatting
if (this.enableFormatting) {
var edits = this.languageService.getFormattingEditsForRange(this.activeFile.fileName, start, offset, this.formatCodeOptions);
offset += this.applyEdits(this.activeFile.fileName, edits, true);
this.editCheckpoint(this.activeFile.fileName);
this.checkPostEditInvariants();
}
// Move the caret to wherever we ended up
@@ -1415,11 +1362,9 @@ module FourSlash {
}
private checkPostEditInvariants() {
if (this.editValidation === IncrementalEditValidation.None) {
return;
}
var incrementalSourceFile = this.languageService.getSourceFile(this.activeFile.fileName);
Utils.assertInvariants(incrementalSourceFile, /*parent:*/ undefined);
var incrementalSyntaxDiagnostics = JSON.stringify(Utils.convertDiagnostics(incrementalSourceFile.getSyntacticDiagnostics()));
// Check syntactic structure
@@ -1434,31 +1379,26 @@ module FourSlash {
this.raiseError('Mismatched incremental/reference syntactic diagnostics for file ' + this.activeFile.fileName + '.\n=== Incremental diagnostics ===\n' + incrementalSyntaxDiagnostics + '\n=== Reference Diagnostics ===\n' + referenceSyntaxDiagnostics);
}
var incrementalSourceFileJSON = Utils.sourceFileToJSON(incrementalSourceFile);
var referenceSourceFileJSON = Utils.sourceFileToJSON(referenceSourceFile);
Utils.assertStructuralEquals(incrementalSourceFile, referenceSourceFile);
if (incrementalSyntaxDiagnostics !== referenceSyntaxDiagnostics) {
this.raiseError('Mismatched incremental/reference ast for file ' + this.activeFile.fileName + '.\n=== Incremental AST ===\n' + incrementalSourceFileJSON + '\n=== Reference AST ===\n' + referenceSourceFileJSON);
}
//if (this.editValidation !== IncrementalEditValidation.SyntacticOnly) {
// var compiler = new TypeScript.TypeScriptCompiler();
// for (var i = 0; i < this.testData.files.length; i++) {
// snapshot = this.languageServiceShimHost.getScriptSnapshot(this.testData.files[i].fileName);
// compiler.addFile(this.testData.files[i].fileName, TypeScript.ScriptSnapshot.fromString(snapshot.getText(0, snapshot.getLength())), ts.ByteOrderMark.None, 0, true);
// }
//if (this.editValidation !== IncrementalEditValidation.SyntacticOnly) {
// var compiler = new TypeScript.TypeScriptCompiler();
// for (var i = 0; i < this.testData.files.length; i++) {
// snapshot = this.languageServiceShimHost.getScriptSnapshot(this.testData.files[i].fileName);
// compiler.addFile(this.testData.files[i].fileName, TypeScript.ScriptSnapshot.fromString(snapshot.getText(0, snapshot.getLength())), ts.ByteOrderMark.None, 0, true);
// }
// compiler.addFile('lib.d.ts', TypeScript.ScriptSnapshot.fromString(Harness.Compiler.libTextMinimal), ts.ByteOrderMark.None, 0, true);
// compiler.addFile('lib.d.ts', TypeScript.ScriptSnapshot.fromString(Harness.Compiler.libTextMinimal), ts.ByteOrderMark.None, 0, true);
// for (var i = 0; i < this.testData.files.length; i++) {
// var refSemanticErrs = JSON.stringify(compiler.getSemanticDiagnostics(this.testData.files[i].fileName));
// var incrSemanticErrs = JSON.stringify(this.languageService.getSemanticDiagnostics(this.testData.files[i].fileName));
// for (var i = 0; i < this.testData.files.length; i++) {
// var refSemanticErrs = JSON.stringify(compiler.getSemanticDiagnostics(this.testData.files[i].fileName));
// var incrSemanticErrs = JSON.stringify(this.languageService.getSemanticDiagnostics(this.testData.files[i].fileName));
// if (incrSemanticErrs !== refSemanticErrs) {
// this.raiseError('Mismatched incremental/full semantic errors for file ' + this.testData.files[i].fileName + '\n=== Incremental errors ===\n' + incrSemanticErrs + '\n=== Full Errors ===\n' + refSemanticErrs);
// }
// }
//}
// if (incrSemanticErrs !== refSemanticErrs) {
// this.raiseError('Mismatched incremental/full semantic errors for file ' + this.testData.files[i].fileName + '\n=== Incremental errors ===\n' + incrSemanticErrs + '\n=== Full Errors ===\n' + refSemanticErrs);
// }
// }
//}
}
private fixCaretPosition() {
@@ -1714,8 +1654,8 @@ module FourSlash {
private verifyClassifications(expected: { classificationType: string; text: string; textSpan?: TextSpan }[], actual: ts.ClassifiedSpan[]) {
if (actual.length !== expected.length) {
this.raiseError('verifyClassifications failed - expected total classifications to be ' + expected.length +
', but was ' + actual.length +
jsonMismatchString());
', but was ' + actual.length +
jsonMismatchString());
}
for (var i = 0; i < expected.length; i++) {
@@ -1755,8 +1695,8 @@ module FourSlash {
function jsonMismatchString() {
return ts.sys.newLine +
"expected: '" + ts.sys.newLine + JSON.stringify(expected, (k,v) => v, 2) + "'" + ts.sys.newLine +
"actual: '" + ts.sys.newLine + JSON.stringify(actual, (k, v) => v, 2) + "'";
"expected: '" + ts.sys.newLine + JSON.stringify(expected,(k, v) => v, 2) + "'" + ts.sys.newLine +
"actual: '" + ts.sys.newLine + JSON.stringify(actual,(k, v) => v, 2) + "'";
}
}
@@ -1768,7 +1708,7 @@ module FourSlash {
}
public verifySyntacticClassifications(expected: { classificationType: string; text: string }[]) {
var actual = this.languageService.getSyntacticClassifications(this.activeFile.fileName,
var actual = this.languageService.getSyntacticClassifications(this.activeFile.fileName,
new ts.TextSpan(0, this.activeFile.content.length));
this.verifyClassifications(expected, actual);
@@ -2650,4 +2590,4 @@ module FourSlash {
fileName: fileName
};
}
}
}

View File

@@ -290,6 +290,64 @@ module Utils {
return o;
}
}
export function assertStructuralEquals(node1: ts.Node, node2: ts.Node) {
if (node1 === node2) {
return;
}
assert(node1, "node1");
assert(node2, "node2");
assert.equal(node1.pos, node2.pos, "node1.pos !== node2.pos");
assert.equal(node1.end, node2.end, "node1.end !== node2.end");
assert.equal(node1.kind, node2.kind, "node1.kind !== node2.kind");
assert.equal(node1.flags, node2.flags, "node1.flags !== node2.flags");
// call this on both nodes to ensure all propagated flags have been set (and thus can be
// compared).
assert.equal(ts.containsParseError(node1), ts.containsParseError(node2));
assert.equal(node1.parserContextFlags, node2.parserContextFlags, "node1.parserContextFlags !== node2.parserContextFlags");
ts.forEachChild(node1,
child1 => {
var childName = findChildName(node1, child1);
var child2: ts.Node = (<any>node2)[childName];
assertStructuralEquals(child1, child2);
},
(array1: ts.NodeArray<ts.Node>) => {
var childName = findChildName(node1, array1);
var array2: ts.NodeArray<ts.Node> = (<any>node2)[childName];
assertArrayStructuralEquals(array1, array2);
});
}
function assertArrayStructuralEquals(array1: ts.NodeArray<ts.Node>, array2: ts.NodeArray<ts.Node>) {
if (array1 === array2) {
return;
}
assert(array1, "array1");
assert(array2, "array2");
assert.equal(array1.pos, array2.pos, "array1.pos !== array2.pos");
assert.equal(array1.end, array2.end, "array1.end !== array2.end");
assert.equal(array1.length, array2.length, "array1.length !== array2.length");
for (var i = 0, n = array1.length; i < n; i++) {
assertStructuralEquals(array1[i], array2[i]);
}
}
function findChildName(parent: any, child: any) {
for (var name in parent) {
if (parent.hasOwnProperty(name) && parent[name] === child) {
return name;
}
}
throw new Error("Could not find child in parent");
}
}
module Harness.Path {
@@ -772,7 +830,7 @@ module Harness {
writeFile,
getCanonicalFileName,
useCaseSensitiveFileNames: () => useCaseSensitiveFileNames,
getNewLine: ()=> ts.sys.newLine
getNewLine: () => ts.sys.newLine
};
}
@@ -814,7 +872,7 @@ module Harness {
}
public emitAll(ioHost?: IEmitterIOHost) {
this.compileFiles(this.inputFiles, [], (result) => {
this.compileFiles(this.inputFiles, [],(result) => {
result.files.forEach(file => {
ioHost.writeFile(file.fileName, file.code, false);
});
@@ -824,7 +882,7 @@ module Harness {
result.sourceMaps.forEach(file => {
ioHost.writeFile(file.fileName, file.code, false);
});
}, () => { }, this.compileOptions);
},() => { }, this.compileOptions);
}
public compileFiles(inputFiles: { unitName: string; content: string }[],
@@ -962,7 +1020,7 @@ module Harness {
break;
case 'includebuiltfile':
inputFiles.push({ unitName: setting.value, content: IO.readFile(libFolder + setting.value)});
inputFiles.push({ unitName: setting.value, content: IO.readFile(libFolder + setting.value) });
break;
default:
@@ -1071,7 +1129,7 @@ module Harness {
return ts.removeFileExtension(sourceFileName) + ".d.ts";
}
});
return ts.forEach(result.declFilesCode, declFile => declFile.fileName === dTsFileName ? declFile : undefined);
}
@@ -1584,4 +1642,4 @@ module Harness {
}
// TODO: not sure why Utils.evalFile isn't working with this, eventually will concat it like old compiler instead of eval
eval(Harness.tcServicesFile);
eval(Harness.tcServicesFile);

View File

@@ -9,7 +9,6 @@
//// }
edit.disableFormatting();
diagnostics.setEditValidation(IncrementalEditValidation.SyntacticOnly);
goTo.marker('check');
verify.quickInfoIs('module Mod');

View File

@@ -1,20 +1,18 @@
/// <reference path="fourslash.ts" />
/// <reference path="fourslash.ts" />
////module A {
//// /*var*/
////}
////module /*check*/A {
//// var p;
////}
diagnostics.setEditValidation(IncrementalEditValidation.SyntacticOnly);
goTo.marker('check');
verify.quickInfoExists();
goTo.marker('var');
edit.insert('var o;');
goTo.marker('check');
verify.quickInfoExists();
////}
goTo.marker('check');
verify.quickInfoExists();
goTo.marker('var');
edit.insert('var o;');
goTo.marker('check');
verify.quickInfoExists();

View File

@@ -3,7 +3,6 @@
////module TestModule {
/////**/
////}
debugger;
goTo.marker("");
edit.paste(" class TestClass{\r\n\
private foo;\r\n\

View File

@@ -23,8 +23,6 @@
////second.start();
////second.stop();
diagnostics.setEditValidation(IncrementalEditValidation.None);
goTo.file("findAllRefsOnDefinition-import.ts");
goTo.marker("1");
@@ -38,4 +36,3 @@ verifyOperationIsCancelled(() => verify.referencesCountIs(0) );
cancellation.resetCancelled();
goTo.marker("1");
verify.referencesCountIs(2);

View File

@@ -26,8 +26,6 @@
// this line triggers a semantic/syntactic error check, remove line when 788570 is fixed
edit.insert('');
diagnostics.setTypingFidelity(TypingFidelity.High);
goTo.marker('1');
verify.completionListContains('foo');
verify.completionListContains('foo2');

View File

@@ -30,7 +30,6 @@
// this line triggers a semantic/syntactic error check, remove line when 788570 is fixed
edit.insert('');
diagnostics.setTypingFidelity(TypingFidelity.High);
goTo.marker('1');
verify.completionListContains('foo');

View File

@@ -126,7 +126,6 @@ verify.quickInfoIs('(local var) localVar: string', '');
goTo.marker('30');
verify.quickInfoIs('(parameter) b: string', '');
goTo.marker('31');
debugger;
verify.quickInfoIs('(local var) lambdaVar: (b: string) => string', '');
goTo.marker('32');
verify.quickInfoIs('(parameter) a: number', '');

View File

@@ -3,9 +3,6 @@
//// var f4 = <T>(x: T/**/ ) => {
//// }
// Turn off edit validation. We don't want semantic diagnostics to run until we explicit call it.
fs.diagnostics.setEditValidation(IncrementalEditValidation.None);
fs.goTo.marker();
// Replace the "T" type with the non-existent type 'V'.

View File

@@ -2,7 +2,6 @@
////var x = Object.create(/**/
diagnostics.setEditValidation(IncrementalEditValidation.None);
goTo.marker();
verify.not.completionListIsEmpty();
edit.insert("nu");

View File

@@ -10,8 +10,6 @@
//// }
////}
diagnostics.setEditValidation(IncrementalEditValidation.None);
verify.numberOfErrorsInCurrentFile(0);
// Edit and bind and resolve only var decl

View File

@@ -23,8 +23,6 @@
////second.start();
////second.stop();
diagnostics.setEditValidation(IncrementalEditValidation.None);
goTo.file("findAllRefsOnDefinition-import.ts");
goTo.marker("1");

View File

@@ -14,8 +14,6 @@
////var start: Second.Test.start;
////var stop: Second.Test.stop;
diagnostics.setEditValidation(IncrementalEditValidation.None);
goTo.file("findAllRefsOnDefinition2-import.ts");
goTo.marker("1");

View File

@@ -10,7 +10,6 @@
//// M.y./*4*/dx;
goTo.marker('1');
debugger;
verify.referencesCountIs(1);
goTo.marker('2');
@@ -20,4 +19,4 @@ goTo.marker('3');
verify.referencesCountIs(3);
goTo.marker('4');
verify.referencesCountIs(2);
verify.referencesCountIs(2);

View File

@@ -6,7 +6,6 @@
////{ function h() {
////return 0;
////}}
debugger;
format.document();
verify.currentFileContentIs(
"function f()\n" +
@@ -17,4 +16,3 @@ verify.currentFileContentIs(
" }\n" +
"}"
);

View File

@@ -31,19 +31,6 @@
declare var FourSlash;
enum IncrementalEditValidation {
None = FourSlash.IncrementalEditValidation.None,
SyntacticOnly = FourSlash.IncrementalEditValidation.SyntacticOnly,
Complete = FourSlash.IncrementalEditValidation.Complete
}
enum TypingFidelity {
/** Performs typing and formatting (if formatting is enabled) */
Low = FourSlash.TypingFidelity.Low,
/** Performs typing, checks completion lists, signature help, and formatting (if enabled) */
High = FourSlash.TypingFidelity.High
}
// Return code used by getEmitOutput function to indicate status of the function
// It is a duplicate of the one in types.ts to expose it to testcases in fourslash
enum EmitReturnStatus {
@@ -101,14 +88,6 @@ module FourSlashInterface {
public validateTypesAtPositions(...positions: number[]) {
return FourSlash.currentTestState.verifyTypesAgainstFullCheckAtPositions(positions);
}
public setEditValidation(validation: IncrementalEditValidation) {
FourSlash.currentTestState.editValidation = validation;
}
public setTypingFidelity(fidelity: TypingFidelity) {
FourSlash.currentTestState.typingFidelity = fidelity;
}
}
export class goTo {

View File

@@ -7,9 +7,6 @@
////var bbb: string;
/////*1*/
// Disable test triggered type check
diagnostics.setEditValidation(IncrementalEditValidation.None);
goTo.marker("1");
verify.completionListContains("aaa");
verify.completionListContains("bbb");

View File

@@ -14,5 +14,4 @@
//// y : number;
//// }
debugger;
verify.baselineGetEmitOutput();

View File

@@ -14,5 +14,4 @@
// @emitThisFile: true
//// var x:string = "hello";
debugger;
verify.baselineGetEmitOutput();

View File

@@ -19,5 +19,4 @@
// @Filename: inputFile5.js
//// var x2 = 1000;
debugger;
verify.baselineGetEmitOutput();

View File

@@ -4,9 +4,7 @@
/////*1*/
////interface Foo {
//// setISO8601(dString): Date;
////}
diagnostics.setEditValidation(IncrementalEditValidation.None);
////}
// Do resolve without typeCheck
goTo.marker('1');
@@ -14,4 +12,4 @@ edit.insert("alert(");
verify.currentSignatureHelpIs("alert(message?: any): void");
// TypeCheck
verify.errorExistsAfterMarker('1');
verify.errorExistsAfterMarker('1');

View File

@@ -20,7 +20,5 @@
// Force a syntax tree ot be created.
verify.noMatchingBracePositionInCurrentFile(0);
// make sure we check the tree after every edit.
diagnostics.setTypingFidelity(TypingFidelity.High);
goTo.marker('1');
edit.insert('Fo');

View File

@@ -9,10 +9,8 @@
//// }
////}
////var val = new c1();
////var b = val.p1;
/////*1*/b;
diagnostics.setEditValidation(IncrementalEditValidation.None);
////var b = val.p1;
/////*1*/b;
// Resolve without typeCheck
goTo.marker('1');

View File

@@ -7,9 +7,7 @@
//// }
////}
////var val = new c1("hello");
/////*1*/val;
diagnostics.setEditValidation(IncrementalEditValidation.None);
/////*1*/val;
// Do resolve without typeCheck
goTo.marker('1');

View File

@@ -19,13 +19,10 @@
//// });
////}
////var val = foo(["myString1", "myString2"]);
/////*1*/val;
/////*1*/val;
diagnostics.setEditValidation(IncrementalEditValidation.None);
// Do resolve without typeCheck
goTo.marker('1');
verify.quickInfoIs("(var) val: string");
// TypeCheck
verify.numberOfErrorsInCurrentFile(1);
verify.numberOfErrorsInCurrentFile(1);

View File

@@ -12,7 +12,6 @@
goTo.marker("1");
verify.quickInfoIs('(function) foo(): void');
goTo.marker("2");
debugger;
verify.quickInfoIs('(local function) bar2(): void');
goTo.marker("3");
verify.quickInfoIs('(local function) bar3(): void');

View File

@@ -8,7 +8,7 @@
////}
////function a() {
//// /* %^ */ }/*3*/
debugger;
format.document();
goTo.marker('1');
verify.currentLineContentIs('function test() /* %^ */ {');

View File

@@ -16,7 +16,5 @@
//// var /*1*/r4 = a(1, true);
////}
diagnostics.setEditValidation(IncrementalEditValidation.None);
goTo.marker('1');
verify.quickInfoIs("(var) r4: number");
verify.quickInfoIs("(var) r4: number");

View File

@@ -12,8 +12,6 @@
//// var r/*2*/4 = b.b/*1*/ar; // string
////}
diagnostics.setEditValidation(IncrementalEditValidation.None);
goTo.marker('1');
verify.quickInfoIs("(property) B<string>.bar: string", undefined);
edit.deleteAtCaret(1);

View File

@@ -15,8 +15,6 @@
//// var r = a.fo/*1*/o + a.bar;
////}
diagnostics.setEditValidation(IncrementalEditValidation.None);
goTo.marker('1');
verify.quickInfoIs("(property) M2.A.foo: string", undefined);
verify.numberOfErrorsInCurrentFile(0);

View File

@@ -10,6 +10,5 @@
////}
////new class/*1*/InheritingSpecializedClass();
diagnostics.setEditValidation(IncrementalEditValidation.None);
goTo.marker('1');
verify.quickInfoExists();

View File

@@ -2,13 +2,12 @@
// @Filename: signatureHelpInFunctionCallOnFunctionDeclarationInMultipleFiles_file0.ts
////declare function fn(x: string, y: number);
// @Filename: signatureHelpInFunctionCallOnFunctionDeclarationInMultipleFiles_file1.ts
////declare function fn(x: string);
// @Filename: signatureHelpInFunctionCallOnFunctionDeclarationInMultipleFiles_file2.ts
////fn(/*1*/
diagnostics.setEditValidation(IncrementalEditValidation.None);
goTo.marker('1');
////fn(/*1*/
goTo.marker('1');
verify.signatureHelpCountIs(2);

View File

@@ -8,7 +8,6 @@
//// }
////}
diagnostics.setEditValidation(IncrementalEditValidation.None);
goTo.marker("1");
edit.insert("super(");
verify.currentSignatureHelpIs("B(x: string): B");

View File

@@ -5,7 +5,7 @@
////return[1];/*2*/
////return ;/*3*/
////}
debugger;
format.document();
goTo.marker("1");
verify.currentLineContentIs(" return 1;");

View File

@@ -13,8 +13,6 @@
//// }
////
diagnostics.setEditValidation(IncrementalEditValidation.SyntacticOnly);
goTo.marker('addParam');
edit.insert(", X");

View File

@@ -1,28 +1,25 @@
/// <reference path="fourslash.ts" />
/// <reference path="fourslash.ts" />
/////*start*/class Point implements /*IPointRef*/IPoint {
//// getDist() {
//// ssss;
//// }
////}/*end*/
// make sure no typeCheck is triggered after edit
diagnostics.setEditValidation(IncrementalEditValidation.None);
// Edit to invalidate the intial typeCheck state
goTo.eof();
edit.insertLine("");
// Attempt to resolve a symbol
goTo.marker("IPointRef");
verify.quickInfoIs(""); // not found
// trigger typecheck after the partial resolve, we should see errors
verify.errorExistsAfterMarker("IPointRef");
goTo.eof();
edit.insertLine("");
// one more time with full typecheck
verify.errorExistsAfterMarker("IPointRef");
////}/*end*/
// Edit to invalidate the intial typeCheck state
goTo.eof();
edit.insertLine("");
// Attempt to resolve a symbol
goTo.marker("IPointRef");
verify.quickInfoIs(""); // not found
// trigger typecheck after the partial resolve, we should see errors
verify.errorExistsAfterMarker("IPointRef");
goTo.eof();
edit.insertLine("");
// one more time with full typecheck
verify.errorExistsAfterMarker("IPointRef");

View File

@@ -59,7 +59,7 @@ module ts {
Utils.assertInvariants(incrementalNewTree, /*parent:*/ undefined);
// We should get the same tree when doign a full or incremental parse.
assertStructuralEquals(newTree, incrementalNewTree);
Utils.assertStructuralEquals(newTree, incrementalNewTree);
// We should also get the exact same set of diagnostics.
assertSameDiagnostics(newTree, incrementalNewTree);
@@ -78,60 +78,6 @@ module ts {
return incrementalNewTree;
}
function assertStructuralEquals(node1: Node, node2: Node) {
if (node1 === node2) {
return;
}
assert(node1, "node1");
assert(node2, "node2");
assert.equal(node1.pos, node2.pos, "node1.pos !== node2.pos");
assert.equal(node1.end, node2.end, "node1.end !== node2.end");
assert.equal(node1.kind, node2.kind, "node1.kind !== node2.kind");
assert.equal(node1.flags, node2.flags, "node1.flags !== node2.flags");
assert.equal(node1.parserContextFlags, node2.parserContextFlags, "node1.parserContextFlags !== node2.parserContextFlags");
forEachChild(node1,
child1 => {
var childName = findChildName(node1, child1);
var child2: Node = (<any>node2)[childName];
assertStructuralEquals(child1, child2);
},
(array1: NodeArray<Node>) => {
var childName = findChildName(node1, array1);
var array2: NodeArray<Node> = (<any>node2)[childName];
assertArrayStructuralEquals(array1, array2);
});
}
function assertArrayStructuralEquals(array1: NodeArray<Node>, array2: NodeArray<Node>) {
if (array1 === array2) {
return;
}
assert(array1, "array1");
assert(array2, "array2");
assert.equal(array1.pos, array2.pos, "array1.pos !== array2.pos");
assert.equal(array1.end, array2.end, "array1.end !== array2.end");
assert.equal(array1.length, array2.length, "array1.length !== array2.length");
for (var i = 0, n = array1.length; i < n; i++) {
assertStructuralEquals(array1[i], array2[i]);
}
}
function findChildName(parent: any, child: any) {
for (var name in parent) {
if (parent.hasOwnProperty(name) && parent[name] === child) {
return name;
}
}
throw new Error("Could not find child in parent");
}
function reusedElements(oldNode: SourceFile, newNode: SourceFile): number {
var allOldElements = collectElements(oldNode);
var allNewElements = collectElements(newNode);