Merge branch 'master' into letAndConst

This commit is contained in:
Mohamed Hegazy
2014-10-24 10:32:21 -07:00
82 changed files with 7858 additions and 1363 deletions
-71
View File
@@ -7945,77 +7945,6 @@ module ts {
return node.parent && node.parent.kind === SyntaxKind.TypeReference;
}
function isExpression(node: Node): boolean {
switch (node.kind) {
case SyntaxKind.ThisKeyword:
case SyntaxKind.SuperKeyword:
case SyntaxKind.NullKeyword:
case SyntaxKind.TrueKeyword:
case SyntaxKind.FalseKeyword:
case SyntaxKind.RegularExpressionLiteral:
case SyntaxKind.ArrayLiteral:
case SyntaxKind.ObjectLiteral:
case SyntaxKind.PropertyAccess:
case SyntaxKind.IndexedAccess:
case SyntaxKind.CallExpression:
case SyntaxKind.NewExpression:
case SyntaxKind.TypeAssertion:
case SyntaxKind.ParenExpression:
case SyntaxKind.FunctionExpression:
case SyntaxKind.ArrowFunction:
case SyntaxKind.PrefixOperator:
case SyntaxKind.PostfixOperator:
case SyntaxKind.BinaryExpression:
case SyntaxKind.ConditionalExpression:
case SyntaxKind.OmittedExpression:
return true;
case SyntaxKind.QualifiedName:
while (node.parent.kind === SyntaxKind.QualifiedName) node = node.parent;
return node.parent.kind === SyntaxKind.TypeQuery;
case SyntaxKind.Identifier:
if (node.parent.kind === SyntaxKind.TypeQuery) {
return true;
}
// Fall through
case SyntaxKind.NumericLiteral:
case SyntaxKind.StringLiteral:
var parent = node.parent;
switch (parent.kind) {
case SyntaxKind.VariableDeclaration:
case SyntaxKind.Parameter:
case SyntaxKind.Property:
case SyntaxKind.EnumMember:
case SyntaxKind.PropertyAssignment:
return (<VariableDeclaration>parent).initializer === node;
case SyntaxKind.ExpressionStatement:
case SyntaxKind.IfStatement:
case SyntaxKind.DoStatement:
case SyntaxKind.WhileStatement:
case SyntaxKind.ReturnStatement:
case SyntaxKind.WithStatement:
case SyntaxKind.SwitchStatement:
case SyntaxKind.CaseClause:
case SyntaxKind.ThrowStatement:
case SyntaxKind.SwitchStatement:
return (<ExpressionStatement>parent).expression === node;
case SyntaxKind.ForStatement:
return (<ForStatement>parent).initializer === node ||
(<ForStatement>parent).condition === node ||
(<ForStatement>parent).iterator === node;
case SyntaxKind.ForInStatement:
return (<ForInStatement>parent).variable === node ||
(<ForInStatement>parent).expression === node;
case SyntaxKind.TypeAssertion:
return node === (<TypeAssertion>parent).operand;
default:
if (isExpression(parent)) {
return true;
}
}
}
return false;
}
function isTypeNode(node: Node): boolean {
if (SyntaxKind.FirstTypeNode <= node.kind && node.kind <= SyntaxKind.LastTypeNode) {
return true;
+71
View File
@@ -67,6 +67,77 @@ module ts {
return identifier.kind === SyntaxKind.Missing ? "(Missing)" : getTextOfNode(identifier);
}
export function isExpression(node: Node): boolean {
switch (node.kind) {
case SyntaxKind.ThisKeyword:
case SyntaxKind.SuperKeyword:
case SyntaxKind.NullKeyword:
case SyntaxKind.TrueKeyword:
case SyntaxKind.FalseKeyword:
case SyntaxKind.RegularExpressionLiteral:
case SyntaxKind.ArrayLiteral:
case SyntaxKind.ObjectLiteral:
case SyntaxKind.PropertyAccess:
case SyntaxKind.IndexedAccess:
case SyntaxKind.CallExpression:
case SyntaxKind.NewExpression:
case SyntaxKind.TypeAssertion:
case SyntaxKind.ParenExpression:
case SyntaxKind.FunctionExpression:
case SyntaxKind.ArrowFunction:
case SyntaxKind.PrefixOperator:
case SyntaxKind.PostfixOperator:
case SyntaxKind.BinaryExpression:
case SyntaxKind.ConditionalExpression:
case SyntaxKind.OmittedExpression:
return true;
case SyntaxKind.QualifiedName:
while (node.parent.kind === SyntaxKind.QualifiedName) node = node.parent;
return node.parent.kind === SyntaxKind.TypeQuery;
case SyntaxKind.Identifier:
if (node.parent.kind === SyntaxKind.TypeQuery) {
return true;
}
// Fall through
case SyntaxKind.NumericLiteral:
case SyntaxKind.StringLiteral:
var parent = node.parent;
switch (parent.kind) {
case SyntaxKind.VariableDeclaration:
case SyntaxKind.Parameter:
case SyntaxKind.Property:
case SyntaxKind.EnumMember:
case SyntaxKind.PropertyAssignment:
return (<VariableDeclaration>parent).initializer === node;
case SyntaxKind.ExpressionStatement:
case SyntaxKind.IfStatement:
case SyntaxKind.DoStatement:
case SyntaxKind.WhileStatement:
case SyntaxKind.ReturnStatement:
case SyntaxKind.WithStatement:
case SyntaxKind.SwitchStatement:
case SyntaxKind.CaseClause:
case SyntaxKind.ThrowStatement:
case SyntaxKind.SwitchStatement:
return (<ExpressionStatement>parent).expression === node;
case SyntaxKind.ForStatement:
return (<ForStatement>parent).initializer === node ||
(<ForStatement>parent).condition === node ||
(<ForStatement>parent).iterator === node;
case SyntaxKind.ForInStatement:
return (<ForInStatement>parent).variable === node ||
(<ForInStatement>parent).expression === node;
case SyntaxKind.TypeAssertion:
return node === (<TypeAssertion>parent).operand;
default:
if (isExpression(parent)) {
return true;
}
}
}
return false;
}
export function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): Diagnostic {
node = getErrorSpanForNode(node);
var file = getSourceFileOfNode(node);
+89 -32
View File
@@ -985,15 +985,85 @@ module FourSlash {
return item.parameters[currentParam];
}
private alignmentForExtraInfo = 50;
private spanInfoToString(pos: number, spanInfo: TypeScript.TextSpan, prefixString: string) {
var resultString = "SpanInfo: " + JSON.stringify(spanInfo);
if (spanInfo) {
var spanString = this.activeFile.content.substr(spanInfo.start(), spanInfo.length());
var spanLineMap = ts.getLineStarts(spanString);
for (var i = 0; i < spanLineMap.length; i++) {
if (!i) {
resultString += "\n";
}
resultString += prefixString + spanString.substring(spanLineMap[i], spanLineMap[i + 1]);
}
resultString += "\n" + prefixString + ":=> (" + this.getLineColStringAtPosition(spanInfo.start()) + ") to (" + this.getLineColStringAtPosition(spanInfo.end()) + ")";
}
return resultString;
}
private baselineCurrentFileLocations(getSpanAtPos: (pos: number) => TypeScript.TextSpan): string {
var fileLineMap = ts.getLineStarts(this.activeFile.content);
var nextLine = 0;
var resultString = "";
var currentLine: string;
var previousSpanInfo: string;
var startColumn: number;
var length: number;
var prefixString = " >";
var addSpanInfoString = () => {
if (previousSpanInfo) {
resultString += currentLine;
var thisLineMarker = repeatString(startColumn, " ") + repeatString(length, "~");
thisLineMarker += repeatString(this.alignmentForExtraInfo - thisLineMarker.length - prefixString.length + 1, " ");
resultString += thisLineMarker;
resultString += "=> Pos: (" + (pos - length) + " to " + (pos - 1) + ") ";
resultString += " " + previousSpanInfo;
previousSpanInfo = undefined;
}
};
for (var pos = 0; pos < this.activeFile.content.length; pos++) {
if (pos === 0 || pos === fileLineMap[nextLine]) {
nextLine++;
addSpanInfoString();
if (resultString.length) {
resultString += "\n--------------------------------";
}
currentLine = "\n" + nextLine.toString() + repeatString(3 - nextLine.toString().length, " ") + ">" + this.activeFile.content.substring(pos, fileLineMap[nextLine]) + "\n ";
startColumn = 0;
length = 0;
}
var spanInfo = this.spanInfoToString(pos, getSpanAtPos(pos), prefixString);
if (previousSpanInfo && previousSpanInfo !== spanInfo) {
addSpanInfoString();
previousSpanInfo = spanInfo;
startColumn = startColumn + length;
length = 1;
}
else {
previousSpanInfo = spanInfo;
length++;
}
}
addSpanInfoString();
return resultString;
function repeatString(count: number, char: string) {
var result = "";
for (var i = 0; i < count; i++) {
result += char;
}
return result;
}
}
public getBreakpointStatementLocation(pos: number) {
this.taoInvalidReason = 'getBreakpointStatementLocation NYI';
var spanInfo = this.languageService.getBreakpointStatementAtPosition(this.activeFile.fileName, pos);
var resultString = "\n**Pos: " + pos + " SpanInfo: " + JSON.stringify(spanInfo) + "\n** Statement: ";
if (spanInfo !== null) {
resultString = resultString + this.activeFile.content.substr(spanInfo.start(), spanInfo.length());
}
return resultString;
return this.languageService.getBreakpointStatementAtPosition(this.activeFile.fileName, pos);
}
public baselineCurrentFileBreakpointLocations() {
@@ -1003,12 +1073,7 @@ module FourSlash {
"Breakpoint Locations for " + this.activeFile.fileName,
this.testData.globalOptions[testOptMetadataNames.baselineFile],
() => {
var fileLength = this.languageServiceShimHost.getScriptSnapshot(this.activeFile.fileName).getLength();
var resultString = "";
for (var pos = 0; pos < fileLength; pos++) {
resultString = resultString + this.getBreakpointStatementLocation(pos);
}
return resultString;
return this.baselineCurrentFileLocations(pos => this.getBreakpointStatementLocation(pos));
},
true /* run immediately */);
}
@@ -1056,7 +1121,7 @@ module FourSlash {
}
public printBreakpointLocation(pos: number) {
Harness.IO.log(this.getBreakpointStatementLocation(pos));
Harness.IO.log("\n**Pos: " + pos + " " + this.spanInfoToString(pos, this.getBreakpointStatementLocation(pos), " "));
}
public printBreakpointAtCurrentLocation() {
@@ -1502,7 +1567,7 @@ module FourSlash {
throw new Error('verifyCaretAtMarker failed - expected to be in file "' + pos.fileName + '", but was in file "' + this.activeFile.fileName + '"');
}
if (pos.position !== this.currentCaretPosition) {
throw new Error('verifyCaretAtMarker failed - expected to be at marker "/*' + markerName + '*/, but was at position ' + this.currentCaretPosition + '(' + this.getLineColStringAtCaret() + ')');
throw new Error('verifyCaretAtMarker failed - expected to be at marker "/*' + markerName + '*/, but was at position ' + this.currentCaretPosition + '(' + this.getLineColStringAtPosition(this.currentCaretPosition) + ')');
}
}
@@ -1566,10 +1631,10 @@ module FourSlash {
this.taoInvalidReason = 'verifyCurrentNameOrDottedNameSpanText NYI';
var span = this.languageService.getNameOrDottedNameSpan(this.activeFile.fileName, this.currentCaretPosition, this.currentCaretPosition);
if (span === null) {
if (!span) {
this.raiseError('verifyCurrentNameOrDottedNameSpanText\n' +
'\tExpected: "' + text + '"\n' +
'\t Actual: null');
'\t Actual: undefined');
}
var actual = this.languageServiceShimHost.getScriptSnapshot(this.activeFile.fileName).getText(span.start(), span.end());
@@ -1581,12 +1646,8 @@ module FourSlash {
}
private getNameOrDottedNameSpan(pos: number) {
var spanInfo = this.languageService.getNameOrDottedNameSpan(this.activeFile.fileName, pos, pos);
var resultString = "\n**Pos: " + pos + " SpanInfo: " + JSON.stringify(spanInfo) + "\n** Statement: ";
if (spanInfo !== null) {
resultString = resultString + this.languageServiceShimHost.getScriptSnapshot(this.activeFile.fileName).getText(spanInfo.start(), spanInfo.end());
}
return resultString;
this.taoInvalidReason = 'getNameOrDottedNameSpan NYI';
return this.languageService.getNameOrDottedNameSpan(this.activeFile.fileName, pos, pos);
}
public baselineCurrentFileNameOrDottedNameSpans() {
@@ -1596,18 +1657,14 @@ module FourSlash {
"Name OrDottedNameSpans for " + this.activeFile.fileName,
this.testData.globalOptions[testOptMetadataNames.baselineFile],
() => {
var fileLength = this.languageServiceShimHost.getScriptSnapshot(this.activeFile.fileName).getLength();
var resultString = "";
for (var pos = 0; pos < fileLength; pos++) {
resultString = resultString + this.getNameOrDottedNameSpan(pos);
}
return resultString;
return this.baselineCurrentFileLocations(pos =>
this.getNameOrDottedNameSpan(pos));
},
true /* run immediately */);
}
public printNameOrDottedNameSpans(pos: number) {
Harness.IO.log(this.getNameOrDottedNameSpan(pos));
Harness.IO.log(this.spanInfoToString(pos, this.getNameOrDottedNameSpan(pos), "**"));
}
private verifyClassifications(expected: { classificationType: string; text: string; textSpan?: TextSpan }[], actual: ts.ClassifiedSpan[]) {
@@ -2114,8 +2171,8 @@ module FourSlash {
return this.languageServiceShimHost.positionToZeroBasedLineCol(this.activeFile.fileName, this.currentCaretPosition).line + 1;
}
private getLineColStringAtCaret() {
var pos = this.languageServiceShimHost.positionToZeroBasedLineCol(this.activeFile.fileName, this.currentCaretPosition);
private getLineColStringAtPosition(position: number) {
var pos = this.languageServiceShimHost.positionToZeroBasedLineCol(this.activeFile.fileName, position);
return 'line ' + (pos.line + 1) + ', col ' + pos.character;
}
+456 -1038
View File
File diff suppressed because it is too large Load Diff
+62 -50
View File
@@ -1952,18 +1952,32 @@ module ts {
return isLabelOfLabeledStatement(node) || isJumpStatementTarget(node);
}
function isRightSideOfQualifiedName(node: Node) {
return node.parent.kind === SyntaxKind.QualifiedName && (<QualifiedName>node.parent).right === node;
}
function isRightSideOfPropertyAccess(node: Node) {
return node.parent.kind === SyntaxKind.PropertyAccess && (<PropertyAccess>node.parent).right === node;
}
function isCallExpressionTarget(node: Node): boolean {
if (node.parent.kind === SyntaxKind.PropertyAccess && (<PropertyAccess>node.parent).right === node)
if (isRightSideOfPropertyAccess(node)) {
node = node.parent;
}
return node.parent.kind === SyntaxKind.CallExpression && (<CallExpression>node.parent).func === node;
}
function isNewExpressionTarget(node: Node): boolean {
if (node.parent.kind === SyntaxKind.PropertyAccess && (<PropertyAccess>node.parent).right === node)
if (isRightSideOfPropertyAccess(node)) {
node = node.parent;
}
return node.parent.kind === SyntaxKind.NewExpression && (<CallExpression>node.parent).func === node;
}
function isNameOfModuleDeclaration(node: Node) {
return node.parent.kind === SyntaxKind.ModuleDeclaration && (<ModuleDeclaration>node.parent).name === node;
}
function isNameOfFunctionDeclaration(node: Node): boolean {
return node.kind === SyntaxKind.Identifier &&
isAnyFunction(node.parent) && (<FunctionDeclaration>node.parent).name === node;
@@ -1996,7 +2010,7 @@ module ts {
function isNameOfExternalModuleImportOrDeclaration(node: Node): boolean {
return node.kind === SyntaxKind.StringLiteral &&
((node.parent.kind === SyntaxKind.ModuleDeclaration && (<ModuleDeclaration>node.parent).name === node) ||
(isNameOfModuleDeclaration(node) ||
(node.parent.kind === SyntaxKind.ImportDeclaration && (<ImportDeclaration>node.parent).externalModuleName === node));
}
@@ -4535,8 +4549,9 @@ module ts {
}
function isTypeReference(node: Node): boolean {
if (node.parent.kind === SyntaxKind.QualifiedName && (<QualifiedName>node.parent).right === node)
if (isRightSideOfQualifiedName(node)) {
node = node.parent;
}
return node.parent.kind === SyntaxKind.TypeReference;
}
@@ -4686,67 +4701,64 @@ module ts {
}
function getNameOrDottedNameSpan(filename: string, startPos: number, endPos: number): TypeScript.TextSpan {
function getTypeInfoEligiblePath(filename: string, position: number, isConstructorValidPosition: boolean) {
var sourceUnit = syntaxTreeCache.getCurrentFileSyntaxTree(filename).sourceUnit();
filename = ts.normalizeSlashes(filename);
// Get node at the location
var node = getTouchingPropertyName(getCurrentSourceFile(filename), startPos);
var ast = TypeScript.ASTHelpers.getAstAtPosition(sourceUnit, position, /*useTrailingTriviaAsLimChar*/ false, /*forceInclusive*/ true);
if (ast === null) {
return null;
}
if (ast.kind() === TypeScript.SyntaxKind.ParameterList && ast.parent.kind() === TypeScript.SyntaxKind.CallSignature && ast.parent.parent.kind() === TypeScript.SyntaxKind.ConstructorDeclaration) {
ast = ast.parent.parent;
}
switch (ast.kind()) {
default:
return null;
case TypeScript.SyntaxKind.ConstructorDeclaration:
var constructorAST = <TypeScript.ConstructorDeclarationSyntax>ast;
if (!isConstructorValidPosition || !(position >= TypeScript.start(constructorAST) && position <= TypeScript.start(constructorAST) + "constructor".length)) {
return null;
}
else {
return ast;
}
case TypeScript.SyntaxKind.FunctionDeclaration:
return null;
case TypeScript.SyntaxKind.MemberAccessExpression:
case TypeScript.SyntaxKind.QualifiedName:
case TypeScript.SyntaxKind.SuperKeyword:
case TypeScript.SyntaxKind.StringLiteral:
case TypeScript.SyntaxKind.ThisKeyword:
case TypeScript.SyntaxKind.IdentifierName:
return ast;
}
if (!node) {
return;
}
filename = TypeScript.switchToForwardSlashes(filename);
switch (node.kind) {
case SyntaxKind.PropertyAccess:
case SyntaxKind.QualifiedName:
case SyntaxKind.StringLiteral:
case SyntaxKind.FalseKeyword:
case SyntaxKind.TrueKeyword:
case SyntaxKind.NullKeyword:
case SyntaxKind.SuperKeyword:
case SyntaxKind.ThisKeyword:
case SyntaxKind.Identifier:
break;
var node = getTypeInfoEligiblePath(filename, startPos, false);
if (!node) return null;
// Cant create the text span
default:
return;
}
while (node) {
if (TypeScript.ASTHelpers.isNameOfMemberAccessExpression(node) ||
TypeScript.ASTHelpers.isRightSideOfQualifiedName(node)) {
node = node.parent;
var nodeForStartPos = node;
while (true) {
if (isRightSideOfPropertyAccess(nodeForStartPos) || isRightSideOfQualifiedName(nodeForStartPos)) {
// If on the span is in right side of the the property or qualified name, return the span from the qualified name pos to end of this node
nodeForStartPos = nodeForStartPos.parent;
}
else if (isNameOfModuleDeclaration(nodeForStartPos)) {
// If this is name of a module declarations, check if this is right side of dotted module name
// If parent of the module declaration which is parent of this node is module declaration and its body is the module declaration that this node is name of
// Then this name is name from dotted module
if (nodeForStartPos.parent.parent.kind === SyntaxKind.ModuleDeclaration &&
(<ModuleDeclaration>nodeForStartPos.parent.parent).body === nodeForStartPos.parent) {
// Use parent module declarations name for start pos
nodeForStartPos = (<ModuleDeclaration>nodeForStartPos.parent.parent).name;
}
else {
// We have to use this name for start pos
break;
}
}
else {
// Is not a member expression so we have found the node for start pos
break;
}
}
return TypeScript.TextSpan.fromBounds(
TypeScript.start(node),
TypeScript.end(node));
return TypeScript.TextSpan.fromBounds(nodeForStartPos.getStart(), node.getEnd());
}
function getBreakpointStatementAtPosition(filename: string, position: number) {
// doesn't use compiler - no need to synchronize with host
filename = TypeScript.switchToForwardSlashes(filename);
var syntaxtree = getSyntaxTree(filename);
return TypeScript.Services.Breakpoints.getBreakpointLocation(syntaxtree, position);
filename = ts.normalizeSlashes(filename);
return BreakpointResolver.spanInSourceFileAtLocation(getCurrentSourceFile(filename), position);
}
function getNavigationBarItems(filename: string): NavigationBarItem[] {