public override int ValidateBreakpointLocation(IVsTextBuffer buffer, int line, int col, TextSpan[] pCodeSpan) { int curline = line; int pos; int linelen; int nlines; buffer.GetLineCount(out nlines); do { buffer.GetPositionOfLine(curline, out pos); buffer.GetLengthOfLine(curline, out linelen); if (linelen == 0) { curline++; continue; } pCodeSpan[0].iStartLine = curline; pCodeSpan[0].iStartIndex = 0; pCodeSpan[0].iEndLine = curline; pCodeSpan[0].iEndIndex = linelen; return(VSConstants.S_OK); }while (linelen == 0 && curline < nlines); //cannot find a better position, just use the one given even if doesn't make sense buffer.GetPositionOfLine(line, out pos); buffer.GetLengthOfLine(line, out linelen); pCodeSpan[0].iStartLine = line; pCodeSpan[0].iStartIndex = 0; pCodeSpan[0].iEndLine = line; pCodeSpan[0].iEndIndex = linelen; return(VSConstants.S_FALSE); }
public override int ValidateBreakpointLocation( IVsTextBuffer buffer, int line, int col, TextSpan[] pCodeSpan ) { if (pCodeSpan != null) { pCodeSpan[0].iStartLine = line; pCodeSpan[0].iStartIndex = col; pCodeSpan[0].iEndLine = line; pCodeSpan[0].iEndIndex = col; if (buffer != null) { int length; buffer.GetLengthOfLine(line, out length); pCodeSpan[0].iStartIndex = 0; pCodeSpan[0].iEndIndex = length; } return(VSConstants.S_OK); } else { return(VSConstants.S_FALSE); } }
public int ValidateBreakpointLocation(IVsTextBuffer pBuffer, int iLine, int iCol, TextSpan[] pCodeSpan) { int len; if (!ErrorHandler.Succeeded(pBuffer.GetLengthOfLine(iLine, out len))) { len = iCol; } if (len <= 0) { return(VSConstants.S_FALSE); } pCodeSpan[0].iStartLine = iLine; pCodeSpan[0].iEndLine = iLine; pCodeSpan[0].iStartIndex = 0; pCodeSpan[0].iEndIndex = len; return(VSConstants.S_OK); }
/// <summary> /// Called to determine if the given location can have a breakpoint applied to it. /// </summary> /// <param name="buffer">The IVsTextBuffer object containing the source file.</param> /// <param name="line">The line number where the breakpoint is to be set.</param> /// <param name="col">The offset into the line where the breakpoint is to be set.</param> /// <param name="pCodeSpan"> /// Returns the TextSpan giving the extent of the code affected by the breakpoint if the /// breakpoint can be set. /// </param> /// <returns> /// If successful, returns S_OK; otherwise returns S_FALSE if there is no code at the given /// position or returns an error code (the validation is deferred until the debug engine is loaded). /// </returns> /// <remarks> /// <para> /// CAUTION: Even if you do not intend to support the ValidateBreakpointLocation but your language /// does support breakpoints, you must override the ValidateBreakpointLocation method and return a /// span that contains the specified line and column; otherwise, breakpoints cannot be set anywhere /// except line 1. You can return E_NOTIMPL to indicate that you do not otherwise support this /// method but the span must always be set. The example shows how this can be done. /// </para> /// <para> /// Since the language service parses the code, it generally knows what is considered code and what /// is not. Normally, the debug engine is loaded and the pending breakpoints are bound to the source. It is at this time the breakpoint location is validated. This method is a fast way to determine if a breakpoint can be set at a particular location without loading the debug engine. /// </para> /// <para> /// You can implement this method to call the ParseSource method with the parse reason of CodeSpan. /// The parser examines the specified location and returns a span identifying the code at that /// location. If there is code at the location, the span identifying that code should be passed to /// your implementation of the CodeSpan method in your version of the AuthoringSink class. Then your /// implementation of the ValidateBreakpointLocation method retrieves that span from your version of /// the AuthoringSink class and returns that span in the pCodeSpan argument. /// </para> /// <para> /// The base method returns E_NOTIMPL. /// </para> /// </remarks> public override int ValidateBreakpointLocation(IVsTextBuffer buffer, int line, int col, TextSpan[] pCodeSpan) { // TODO: Add code to not allow breakpoints to be placed on non-code lines. // TODO: Refactor to allow breakpoint locations to span multiple lines. if (pCodeSpan != null) { pCodeSpan[0].iStartLine = line; pCodeSpan[0].iStartIndex = col; pCodeSpan[0].iEndLine = line; pCodeSpan[0].iEndIndex = col; if (buffer != null) { int length; buffer.GetLengthOfLine(line, out length); pCodeSpan[0].iStartIndex = 0; pCodeSpan[0].iEndIndex = length; } return(VSConstants.S_OK); } else { return(VSConstants.S_FALSE); } }
public override int ValidateBreakpointLocation(IVsTextBuffer buffer, int line, int col, TextSpan[] pCodeSpan) { if (pCodeSpan != null) { pCodeSpan[0].iStartLine = line; pCodeSpan[0].iStartIndex = col; pCodeSpan[0].iEndLine = line; pCodeSpan[0].iEndIndex = col; if (buffer != null) { int length; buffer.GetLengthOfLine(line, out length); pCodeSpan[0].iStartIndex = 0; pCodeSpan[0].iEndIndex = length; } return Microsoft.VisualStudio.VSConstants.S_OK; } else { return Microsoft.VisualStudio.VSConstants.S_FALSE; } }
public override int ValidateBreakpointLocation(IVsTextBuffer buffer, int line, int col, TextSpan[] pCodeSpan) { if (pCodeSpan != null) { pCodeSpan[0].iStartLine = line; pCodeSpan[0].iEndLine = line; List<TokenInfo> tokens = new List<TokenInfo>(); if (buffer != null) { int length; buffer.GetLengthOfLine(line, out length); IVsTextLines lines = (IVsTextLines)buffer; string text; lines.GetLineText(line, 0, line, length, out text); Scanner scanner = new Scanner(); scanner.SetSource(text, 0); int state = 0, start, end; int tokenType = -1; while (tokenType != ((int)Tokens.EOF)) { tokenType = scanner.GetNext(ref state, out start, out end); tokens.Add(new TokenInfo(start, end, tokenType, scanner.yytext)); } for (int i = 0; i < tokens.Count; i++) { TokenInfo t = tokens[i]; if (t.type == (int)Tokens.OUTACTION || t.type == (int)Tokens.METHOD || t.type == (int)Tokens.LCASEIDENT || (t.type == (int)Tokens.NUMBER && t.text == "0")) { pCodeSpan[0].iStartIndex = t.start; pCodeSpan[0].iEndIndex = t.end + 1; return Microsoft.VisualStudio.VSConstants.S_OK; } else if (t.type == (int)Tokens.PROC) { //Just a heuristic, if there is a '=' somewhere after this, then we don't want it //Most likely it is Foo = proc or Foo(x,y,z) = proc and we don't want to highlight that bool canUseProc = true; for (int j = i + 1; j < tokens.Count; j++) { if (tokens[j].type == (int)'=') { i = j; canUseProc = false; break; } } if (canUseProc) { pCodeSpan[0].iStartIndex = t.start; pCodeSpan[0].iEndIndex = t.end + 1; return Microsoft.VisualStudio.VSConstants.S_OK; } } } } } return Microsoft.VisualStudio.VSConstants.S_FALSE; }
/// <summary> /// Called to determine if the given location can have a breakpoint applied to it. /// </summary> /// <param name="buffer">The IVsTextBuffer object containing the source file.</param> /// <param name="line">The line number where the breakpoint is to be set.</param> /// <param name="col">The offset into the line where the breakpoint is to be set.</param> /// <param name="pCodeSpan"> /// Returns the TextSpan giving the extent of the code affected by the breakpoint if the /// breakpoint can be set. /// </param> /// <returns> /// If successful, returns S_OK; otherwise returns S_FALSE if there is no code at the given /// position or returns an error code (the validation is deferred until the debug engine is loaded). /// </returns> /// <remarks> /// <para> /// CAUTION: Even if you do not intend to support the ValidateBreakpointLocation but your language /// does support breakpoints, you must override the ValidateBreakpointLocation method and return a /// span that contains the specified line and column; otherwise, breakpoints cannot be set anywhere /// except line 1. You can return E_NOTIMPL to indicate that you do not otherwise support this /// method but the span must always be set. The example shows how this can be done. /// </para> /// <para> /// Since the language service parses the code, it generally knows what is considered code and what /// is not. Normally, the debug engine is loaded and the pending breakpoints are bound to the source. It is at this time the breakpoint location is validated. This method is a fast way to determine if a breakpoint can be set at a particular location without loading the debug engine. /// </para> /// <para> /// You can implement this method to call the ParseSource method with the parse reason of CodeSpan. /// The parser examines the specified location and returns a span identifying the code at that /// location. If there is code at the location, the span identifying that code should be passed to /// your implementation of the CodeSpan method in your version of the AuthoringSink class. Then your /// implementation of the ValidateBreakpointLocation method retrieves that span from your version of /// the AuthoringSink class and returns that span in the pCodeSpan argument. /// </para> /// <para> /// The base method returns E_NOTIMPL. /// </para> /// </remarks> public override int ValidateBreakpointLocation(IVsTextBuffer buffer, int line, int col, TextSpan[] pCodeSpan) { // TODO: Add code to not allow breakpoints to be placed on non-code lines. // TODO: Refactor to allow breakpoint locations to span multiple lines. if (pCodeSpan != null) { pCodeSpan[0].iStartLine = line; pCodeSpan[0].iStartIndex = col; pCodeSpan[0].iEndLine = line; pCodeSpan[0].iEndIndex = col; if (buffer != null) { int length; buffer.GetLengthOfLine(line, out length); pCodeSpan[0].iStartIndex = 0; pCodeSpan[0].iEndIndex = length; } return VSConstants.S_OK; } return VSConstants.S_FALSE; }
public override int ValidateBreakpointLocation(IVsTextBuffer buffer, int line, int col, TextSpan[] pCodeSpan) { if (pCodeSpan != null) { pCodeSpan[0].iStartLine = line; pCodeSpan[0].iEndLine = line; List <TokenInfo> tokens = new List <TokenInfo>(); if (buffer != null) { int length; buffer.GetLengthOfLine(line, out length); IVsTextLines lines = (IVsTextLines)buffer; string text; lines.GetLineText(line, 0, line, length, out text); Scanner scanner = new Scanner(); scanner.SetSource(text, 0); int state = 0, start, end; int tokenType = -1; while (tokenType != ((int)Tokens.EOF)) { tokenType = scanner.GetNext(ref state, out start, out end); tokens.Add(new TokenInfo(start, end, tokenType, scanner.yytext)); } for (int i = 0; i < tokens.Count; i++) { TokenInfo t = tokens[i]; if (t.type == (int)Tokens.OUTACTION || t.type == (int)Tokens.METHOD || t.type == (int)Tokens.LCASEIDENT || (t.type == (int)Tokens.NUMBER && t.text == "0")) { pCodeSpan[0].iStartIndex = t.start; pCodeSpan[0].iEndIndex = t.end + 1; return(Microsoft.VisualStudio.VSConstants.S_OK); } else if (t.type == (int)Tokens.PROC) { //Just a heuristic, if there is a '=' somewhere after this, then we don't want it //Most likely it is Foo = proc or Foo(x,y,z) = proc and we don't want to highlight that bool canUseProc = true; for (int j = i + 1; j < tokens.Count; j++) { if (tokens[j].type == (int)'=') { i = j; canUseProc = false; break; } } if (canUseProc) { pCodeSpan[0].iStartIndex = t.start; pCodeSpan[0].iEndIndex = t.end + 1; return(Microsoft.VisualStudio.VSConstants.S_OK); } } } } } return(Microsoft.VisualStudio.VSConstants.S_FALSE); }