eclipse ASTNode to source code line number - eclipse

Given an ASTNode in eclipse, is there any way to get the corresponding source code line number?

You can get the line number of an ASTNode using the below code
int lineNumber = compilationUnit.getLineNumber(node.getStartPosition()) - 1;
the compilation unit can be obtained from the ASTParser using the below code
ASTParser parser = ASTParser.newParser(AST.JLS3);
// Parse the class as a compilation unit.
parser.setKind(ASTParser.K_COMPILATION_UNIT);
parser.setSource(source); // give your java source here as char array
parser.setResolveBindings(true);
// Return the compiled class as a compilation unit
CompilationUnit compilationUnit = parser.createAST(null);
Then you can use the ASTVisitor pattern to visit the type of required node (say MethodDeclaration node) using the below code:
compilationUnit.accept(new ASTVisitor() {
public boolean visit(MethodDeclaration node) {
int lineNumber = compilationUnit.getLineNumber(node.getStartPosition()) - 1;
return true;
}
});

ASTNode has getStartPosition() and getLength() methods which deal with character offsets. To convert from a character offset to a line number you should use CompilationUnit's getLineNumber() method. CompilationUnit is the root of your AST tree.

Apart from the general solution that has already been described, there is another one that applies if you need the line number of an ASTNode including leading whitespaces or potential comments written in front of the ASTNode. Then you can use:
int lineNumber = compilationUnit.getLineNumber(compilationUnit.getExtendedStartPosition(astNode))
See the API:
Returns the extended start position of the given node. Unlike ASTNode.getStartPosition() and ASTNode.getLength(), the extended source range may include comments and whitespace immediately before or after the normal source range for the node.

Related

Eclipse formatter: How to move comment between method name and open brace to always have open brace on same line as method declaration

I have code that looks like this, that I'm trying to format
Original code:
public int doThing(int a) // -incredibly useful comment here
{
int ab = a+1;
return ab;
}
I want it to look like this
public int doThing() { // -incredibly useful comment here
int ab = a+1;
return ab;
}
If I try to turn on the Brace position -> Method Declaration -> Same line option and run the formatter, any code with a comment in the position "breaks" the formatter, and I get an output for my example that looks the same as the original code, but methods without a comment have the correct formatting (meaning the results are inconsistent).
Is it possible with the eclipse formatter to get the style I want? I'm trying to run it against a large amount of code, and would prefer not to have to fix these all manually to get a consistent brace position.
The problem here is that is not formatting but rewriting. Using File Search + regular expression + Replace could do that in bulk.
Try this regex
^(\s*(?:public|private|protected)\s+[^(]+\([^)]*\))(\s*\/\/[^/]+)\R\s*\{
On File Search ( Ctrl + H)
Hit Replace and use $1 { $2\n as replacement
Code should compile after the refactoring.
UPDATE:
Fixed regex part that represents function arguments
\([^)]*\)
Full Regex matches these cases
public int doSmthg() // coment here
{
return 1;
}
private String doSmthgElse(String arg) // coment here
{
return arg;
}

find variable Declaration reference Abstract syntax tree eclipse cdt C code

I have a c code like this
int x;
x = 5;
I used eclipse cdt to generate the AST, and traverse on it, so this is the code of the traversed class
public class RuleChk extends AbstractRule {
public RuleChk(IASTTranslationUnit ast) {
super("RuleChk", false, ast);
shouldVisitDeclarations = true;
shouldVisitParameterDeclarations = true;
}
#Override
public int visit(IASTSimpleDeclaration simpleDecl) {
//if this node has init, e.g: x = 5, do business
if(VisitorUtil.containNode(simpleDecl, CASTExpressionStatement){
// Now I have the x = 5 node,
// I want to get the reference node of it's declaration
// I mean (int x;) node
IASTNode declNode = ?????
}
return super.visit(parameterDeclaration);
}
}
what I want to visit the node that only has assignation(Initialization) and get the reference of declaration node for that varaiable.
I'm not sure how VisitorUtil works (it's not from the CDT code), but I assume it gives you a way to access the the found node. So:
Given the IASTExpressionStatement node that was found, use IASTExpression.getExpression() to get the contained expression.
See if it's an IASTBinaryExpression, and that is getOperator() is IASTBinaryExpression.op_assign.
Use IASTBinaryExpression.getOperand1() to get the assignment expression's left subexpression. Check that it's an IASTIdExpression, and get the variable it names via IASTIdExpression.getName().
Now that you have the name, use IASTName.resolveBinding() to get the variable's binding. This is the variable's representation in the semantic program model.
To find the variable's definition, use IASTTranslationUnit.getDefinitionsInAST(IBinding) if you only want it to look in the current file, or IASTTranslationUnit.getDefinitions(IBinding) if you want it to look in included header files as well (the latter requires the project to be indexed). The IASTTranslationUnit can be obtained from any IASTNode via IASTNode.getTranslationUnit().

Working with Java; HashMaps and ArrayLists not compiling in Eclipse or BlueJay

I am having trouble getting HashMaps and ArrayLists to work correctly on my computer. I have tried using my own code, and copying samples from textbooks and online to make sure my syntax is correct, but thus far neither Eclipse or BlueJay will let me "add" or "put" things into these data structures. Here are some examples of what I have done.
package issues;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.*;
public class StructureIssues {
/*
* HashMap Attempt
*/
HashMap<Integer, String> numberNames = new HashMap<Integer, String>();
numberNames.put(new Integer(1), "hi");// here, I have syntax errors asking me to
// delete the (), and I have misplaced
// constructs on the dot.
//When the above line didn't work, I tried creating the objects
//outside of the parameter list...
Integer one = new Integer(1);
String myString = "hi";
numberNames.put(one, myString); //here it just complains about the parenthesis
//similar results for <String,String> and generic
/*
* ArrayList Attempt
*/
ArrayList<String> tryStrings = new ArrayList<String>();
String tryOne = "one";
tryStrings.add(tryOne);//Syntax error on tryOne; variable declarator ID expected
//also, syntax error on the dot; misplaced constructs
ArrayList<Integer> tryInts = new ArrayList<Integer>();
tryInts.add(new Integer(4));//Syntax error on add; expected "=" after it.
//Below, I have copied two lines from Big Java by Horstmann.
//The results are the same as my first String ArrayList attempt.
ArrayList<String> friends = new ArrayList<String>();
friends.add("Cindy");
}
I did find one or two questions similar to mine, and I followed their advice, but so far I've had no luck. Here is what I have tried to far to figure this out:
-Reinstalled my JDK package several times, trying both 64 and 32-bit
-Reinstalled eclipse Indigo several times, trying both 64 and 32-bit
-In eclipse, gone to Project->Properties->Java Compiler. My java compliance is JavaSE-1.7
-In eclipse, gone to Window->Preferences->InstalledJREs. I have jre7 with Standard VM.
-I have tried right clicking on my jre System Library in my packages, and changing to JavaSE-1.6, 1.7, and checking the default workspace box for jre7.
-I have tried similar code in BlueJay because I wanted to try another IDE to see if it was eclipse or my computer. I received: "identifier" expected. It highlighted tryStrings.add("one");
Am I doing something silly here? Any advice you guys could offer would be greatly appreciated. Thank you for your time.
Your code is not in any method. You may declare and initialize fields in a class. But using these fields should be done in methods (or constructors).
Problem is that the code is not in any method. Where you are calling the put method is the area where you declare the variables. see this modified code. I made the variable static so that it can be called from the main method.
public class StructureIssues {
/*
* HashMap Attempt
*/
static HashMap<Integer, String> numberNames = new HashMap<Integer, String>();
public static void main(String args[]) {
numberNames.put(new Integer(1), "hi");// here, I have syntax errors
// asking me to
// delete the (), and I have
// misplaced
// constructs on the dot.
// When the above line didn't work, I tried creating the objects
// outside of the parameter list...
Integer one = new Integer(1);
String myString = "hi";
numberNames.put(one, myString); // here it just complains about the
// parenthesis
// similar results for <String,String>
// and generic
/*
* ArrayList Attempt
*/
ArrayList<String> tryStrings = new ArrayList<String>();
String tryOne = "one";
tryStrings.add(tryOne);// Syntax error on tryOne; variable declarator ID
// expected
// also, syntax error on the dot; misplaced
// constructs
ArrayList<Integer> tryInts = new ArrayList<Integer>();
tryInts.add(new Integer(4));// Syntax error on add; expected "=" after
// it.
// Below, I have copied two lines from Big Java by Horstmann.
// The results are the same as my first String ArrayList attempt.
ArrayList<String> friends = new ArrayList<String>();
friends.add("Cindy");
}
}

How could I search references to a field on a AST or a CompilationUnit in eclipse?

Hi,
I'm developing an Eclipse plugin. I
need to find all the references in the
source using AST's or jdt.core.dom
or something like that. I need this
references like ASTNodes in order to
get the parent node and check several
things in the expression where
references are involved.
Thanks beforehand.
Edited:
I want to concrete a little more, My problem is that I try to catch some references to a constant but... I have not idea how I can do to catch in the matches this references. I need check the expressions which the references to a determined constant are involved. I only get the source of the method where they are used.
I think the problem is the scope or the pattern:
pattern = SearchPattern.createPattern(field, IJavaSearchConstants.REFERENCES);
scope = SearchEngine.createJavaSearchScope(declaringType.getMethods());
Thanks beforehand!
I used something like:
Search for the declaration of an
method, returns an IMethod
Search for references to the
IMethod, record those IMethods
For each IMethod returned, create an
AST from its compilation unit
Searching for declarations or references looks like the following code.
SearchRequestor findMethod = ...; // do something with the search results
SearchEngine engine = new SearchEngine();
IJavaSearchScope workspaceScope = SearchEngine.createWorkspaceScope();
SearchPattern pattern = SearchPattern.createPattern(searchString,
IJavaSearchConstants.METHOD, IJavaSearchConstants.DECLARATIONS,
SearchPattern.R_EXACT_MATCH);
SearchParticipant[] participant = new SearchParticipant[] { SearchEngine
.getDefaultSearchParticipant() };
engine.search(pattern, participant, workspaceScope, findMethod,
monitor);
Once you have your IMethod references, you can get to the AST using:
ASTParser parser = ASTParser.newParser(AST.JLS3);
parser.setResolveBindings(true);
if (methodToSearch.isBinary()) {
parser.setSource(methodToSearch.getClassFile());
} else {
parser.setSource(methodToSearch.getCompilationUnit());
}
CompilationUnit cu = (CompilationUnit) parser.createAST(null);
See http://help.eclipse.org/helios/index.jsp?topic=/org.eclipse.jdt.doc.isv/guide/jdt_int_core.htm for more details on java search, the java model, and the AST.

JDT ASTParser to get the value of a string field

Is there a way to use jdt ASTParser to get the value of a String field declared in a java file. Actually what I need is to resolve any possible dependencies from other classes e.g.
public String str = "somethig"+SomeTherClass.SOMETHING_ELSE.
I figured it out ...it was quite simple actually ..here's the code:
ICompilationUnit cu = ....
ASTParser parser = ASTParser.newParser(AST.JLS3);
parser.setResolveBindings(true);
parser.setSource(cu);
parser.setStatementsRecovery(true);
parser.setBindingsRecovery(true);
ASTNode node = parser.createAST(null);
node.accept(new YourVisitor());
Then in your implementation of the ASTVisitor you need to call resolveConstantExpressionValue() on the node being visited.