blob: e000140b0d5121dc67d4e2fb256d6c9b9a32a515 [file] [log] [blame]
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;
}
}
}