Skip to content

New tree break points #931

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 31 commits into from
Oct 23, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
06d29a0
Breakpoint span in variable declarations in new language service
sheetalkamat Oct 17, 2014
fbd78b4
Remove the old implementation of the breakpoint resolver
sheetalkamat Aug 31, 2014
cec8146
Changed the namespace from ts.Breakpoints to ts.BreakpointResolver
sheetalkamat Aug 31, 2014
35cdea1
Breakpointspan implementation for function declaration, expression st…
sheetalkamat Oct 17, 2014
abb0acc
Breakpoints for while statement
sheetalkamat Oct 17, 2014
a047d20
Breakpoint span in the doStatement
sheetalkamat Oct 17, 2014
71e96be
Breakpoint span in the debugger statement
sheetalkamat Oct 17, 2014
7425aed
Breakpoints for if else construct
sheetalkamat Oct 17, 2014
6fbf0d6
Breakpoints in labeled statements
sheetalkamat Oct 17, 2014
c81c0bf
Breakpoints in break/continue statements
sheetalkamat Oct 17, 2014
b97f876
Breakpoints in for statement
sheetalkamat Oct 17, 2014
f5731f3
Breakpoints in the for in statement
sheetalkamat Sep 2, 2014
5bdeaa9
Breakpoints in the switch statement
sheetalkamat Oct 18, 2014
3663550
Breakpoint spans in try,catch,finally blocks and throw statement
sheetalkamat Oct 18, 2014
2905217
Breakpoint validation for export assignment
sheetalkamat Oct 18, 2014
d235caf
Breakpoints in import declaration
sheetalkamat Sep 2, 2014
01d4ce2
Breakpoints in enum declaration
sheetalkamat Sep 2, 2014
b54d20d
Breakpoints in module declaration
sheetalkamat Oct 18, 2014
330065f
Breakpoints in classes
sheetalkamat Oct 18, 2014
0cb2e98
Breakpoints in expressions
sheetalkamat Oct 21, 2014
4a8a892
Do not set breakpoints on the blank line or comment only line
sheetalkamat Oct 21, 2014
308670c
Implement getNameOrDottedNameSpan for new compiler
sheetalkamat Oct 21, 2014
933680b
Breakpoint validation in interfaces
sheetalkamat Oct 21, 2014
7a500fb
Set breakpoint on whole enum declaration if set on the enum name of e…
sheetalkamat Oct 21, 2014
a410133
Some reorganizing
sheetalkamat Oct 21, 2014
b72b3ac
Breakpoint span on module and its name is set on whole declaration if…
sheetalkamat Oct 21, 2014
84016da
Breakpoint span on class and its name is set on whole declaration
sheetalkamat Oct 21, 2014
897f23a
Span on whole function if the function is exported
sheetalkamat Oct 21, 2014
e464a3d
Span on whole method/accessors if they are of class declaration
sheetalkamat Oct 21, 2014
e87f18c
Exported variables can have breakpoint even if they do not have initi…
sheetalkamat Oct 22, 2014
3f2211f
Code review feedback update
sheetalkamat Oct 22, 2014
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Jakefile
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ var servicesSources = [
].map(function (f) {
return path.join(compilerDirectory, f);
}).concat([
"breakpoints.ts",
"services.ts",
"shims.ts",
"signatureHelp.ts",
Expand Down
71 changes: 0 additions & 71 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7815,77 +7815,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;
Expand Down
71 changes: 71 additions & 0 deletions src/compiler/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
119 changes: 88 additions & 31 deletions src/harness/fourslash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -985,15 +985,85 @@ module FourSlash {
return item.parameters[currentParam];
}

public getBreakpointStatementLocation(pos: number) {
this.taoInvalidReason = 'getBreakpointStatementLocation NYI';
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;
}
};

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());
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';
return this.languageService.getBreakpointStatementAtPosition(this.activeFile.fileName, pos);
}

public baselineCurrentFileBreakpointLocations() {
Expand All @@ -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 */);
}
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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) + ')');
}
}

Expand Down Expand Up @@ -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());
Expand All @@ -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() {
Expand All @@ -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[]) {
Expand Down Expand Up @@ -2102,8 +2159,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;
}

Expand Down
Loading