| package org.eclipse.jdt.internal.debug.ui.actions; |
| |
| /* |
| * (c) Copyright IBM Corp. 2000, 2001. |
| * All Rights Reserved. |
| */ |
| |
| import org.eclipse.jdt.core.ToolFactory; |
| import org.eclipse.jdt.core.compiler.IScanner; |
| import org.eclipse.jdt.core.compiler.ITerminalSymbols; |
| import org.eclipse.jdt.core.compiler.InvalidInputException; |
| import org.eclipse.jface.text.BadLocationException; |
| import org.eclipse.jface.text.IDocument; |
| |
| public class BreakpointLocationVerifier { |
| |
| /** |
| * Returns the line number closest to the given line number that represents a |
| * valid location for a breakpoint in the given document, or -1 if a valid location |
| * cannot be found. |
| */ |
| public int getValidBreakpointLocation(IDocument doc, int lineNumber) { |
| |
| IScanner scanner = ToolFactory.createScanner(false, false, false, false); |
| boolean found = false; |
| int start = 0, length = 0, token = 0, lastToken = 0; |
| |
| while (!found) { |
| try { |
| start = doc.getLineOffset(lineNumber); |
| length = doc.getLineLength(lineNumber); |
| char[] txt = doc.get(start, length).toCharArray(); |
| scanner.setSource(txt); |
| token = scanner.getNextToken(); |
| if (token == ITerminalSymbols.TokenNameEQUAL) { |
| break; |
| } |
| lastToken = 0; |
| |
| while (token != ITerminalSymbols.TokenNameEOF) { |
| if (token == ITerminalSymbols.TokenNameERROR) { |
| lineNumber++; |
| break; |
| } |
| if (token == ITerminalSymbols.TokenNameIdentifier) { |
| if (lastToken == ITerminalSymbols.TokenNameIdentifier |
| || isPrimitiveTypeToken(lastToken) |
| || lastToken == ITerminalSymbols.TokenNameRBRACKET) { |
| //var declaration..is there initialization |
| //OR method parameters on a line all by themselves |
| lastToken = token; |
| token = scanner.getNextToken(); |
| if (token == ITerminalSymbols.TokenNameEQUAL) { |
| found = true; |
| break; |
| } |
| } |
| if (lastToken == ITerminalSymbols.TokenNameMULTIPLY) { |
| //internal comment line starting with '*' |
| break; |
| } |
| } else if (isNonIdentifierValidToken(token)) { |
| found = true; |
| break; |
| } else if ( |
| lastToken == ITerminalSymbols.TokenNameIdentifier |
| && token != ITerminalSymbols.TokenNameLBRACKET) { |
| found = true; |
| break; |
| } else if ( |
| lastToken == ITerminalSymbols.TokenNameLBRACKET |
| && token == ITerminalSymbols.TokenNameRBRACKET) { |
| //var declaration..is there initialization |
| lastToken = token; |
| token = scanner.getNextToken(); |
| if (token == ITerminalSymbols.TokenNameSEMICOLON) { |
| //no init |
| break; |
| } else if (token == ITerminalSymbols.TokenNameEQUAL) { |
| found = true; |
| break; |
| } |
| |
| continue; |
| } |
| |
| lastToken = token; |
| token = scanner.getNextToken(); |
| } |
| if (!found) { |
| lineNumber++; |
| } |
| } catch (BadLocationException ble) { |
| return -1; |
| } catch (InvalidInputException ie) { |
| //start of a comment "/**" or "/*" |
| lineNumber++; |
| } |
| } |
| // add 1 to the line number - Document is 0 based, JDI is 1 based |
| return lineNumber + 1; |
| } |
| |
| protected boolean isPrimitiveTypeToken(int token) { |
| switch (token) { |
| case ITerminalSymbols.TokenNameboolean : |
| case ITerminalSymbols.TokenNamebyte : |
| case ITerminalSymbols.TokenNamechar : |
| case ITerminalSymbols.TokenNamedouble : |
| case ITerminalSymbols.TokenNamefloat : |
| case ITerminalSymbols.TokenNameint : |
| case ITerminalSymbols.TokenNamelong : |
| case ITerminalSymbols.TokenNameshort : |
| return true; |
| default : |
| return false; |
| } |
| } |
| |
| protected boolean isNonIdentifierValidToken(int token) { |
| switch (token) { |
| case ITerminalSymbols.TokenNamebreak : |
| case ITerminalSymbols.TokenNamecontinue : |
| case ITerminalSymbols.TokenNamereturn : |
| case ITerminalSymbols.TokenNamethis : |
| case ITerminalSymbols.TokenNamesuper : |
| return true; |
| default : |
| return false; |
| } |
| } |
| } |