1

I am writting an ordinary Java application and want to extract all ICompilationUnit of an input project (which is not necessary developed by Eclipse). As I am not developing an Eclipse plugin, I can't use the below code to extract ICompilationUnit:

IWorkspace workspace = ResourcesPlugin.getWorkspace();
IPath path = Path.fromOSString(source.getAbsolutePath());
IFile file = workspace.getRoot().getFileForLocation(path);
ICompilationUnit compilationUnit = (ICompilationUnit) JavaCore.create(file);

Currently, I am using the below code to parse the input Java file. (str contains the source code of input java file)

ASTParser parser = ASTParser.newParser(AST.JLS12);
parser.setSource(str.toCharArray());
parser.setKind(ASTParser.K_COMPILATION_UNIT);
CompilationUnit cu = (CompilationUnit) parser.createAST(null);

However, the below code return null as it was not created from a Java element.

ICompilationUnit icu = (ICompilationUnit)compilationUnit.getJavaElement();

Question: Is there any way to extract ICompilationUnits in an ordinary Java Application?

Arash
  • 11
  • 1
  • What do you mean by _"extract ICompilationUnits"_? With a `CompilationUnit` you can do `cu.accept(new ASTVisitor(true) { ... })` to find specific elements. – howlger Aug 16 '19 at 12:04
  • I want to use SearchEngine(ICompilationUnit[] workingCopies) and because of that I need to extract ICompilationUnit. – Arash Aug 16 '19 at 12:14
  • I see. `getJavaElement` returns `null`, because of `parser.setSource(str.toCharArray());` instead of `parser.setSource(IClassFile)`. I guess it would be easier to use the `ASTVisitor` instead of creating an `IClassFile` and using the `SearchEngine` to find specific elements. What are you searching for? – howlger Aug 16 '19 at 12:27
  • I want to find all calls to methods and fields defined in the project. There is an easy way if I was writing an eclipse plugin. However, as I am writing an standalone application [ResourcesPlugin.getWorkspace();] does not work and I can not write the rest instructions. Let me know if you know a sample code to find references to methods and fields in a standalone java application using JDT. – Arash Aug 16 '19 at 15:05
  • If you add `parser.setEnvironment(...)` to your code, you can use `cu.accept(new ASTVisitor(true) { ... })` to visit the AST nodes. In `ASTVisitor` override the `visit` methods at least for `QualifiedName` and `SimpleName`. With `IBinding binding = node.resolveBinding();` you have a method call or reference if and only if `binding instanceof IMethodBinding` is true and for a field access the following is true: `binding instanceof IVariableBinding` and `((IVariableBinding)binding).isField()`. – howlger Aug 17 '19 at 13:48

1 Answers1

2

The JDT search engine needs an index. Within the IDE the index is created during workspace build. This means without a workspace there is no out-of-the-box approach to using the search engine.

It may in theory be possible to implement your own index, but that can definitely not be recommended.

Two options remain:

  1. As mentioned in a comment use your own traversal of existing classes, or

  2. Let your application initialize a workspace behind the scenes into which your code is imported as real Java projects. After a build of that workbench, the search engine should be available. All this could happen in a headless application with no need to fire up the Eclipse UI.

For inspirations regarding option (2) you could start here:

  • PDE's CoreTestApplication, which is the headless application used, e.g., for running JDT's own tests. A workspace is automatically available in the locations passed using the -data command line argument.
  • JDT's AbstractJavaModelTests, which provides tons of utilities for programmatically creating & configuring Java projects.
  • Subclasses of AbstractJavaModelTests which have gazillions of examples how those Java projects are used, including search.

If you want to see it all live, I suggest you set up a workspace with JDT and PDE projects in source. The easiest way would be to use Oomph for this.

The above CoreTestApplication will be run, if you select any test class, invoke Run as > Run configurations... then create a launch configuration of type JUnit Plug-in Test and on tab Main select Run an application: [No Application] - Headless Mode.

Stephan Herrmann
  • 7,963
  • 2
  • 27
  • 38
  • Could you please provide a sample code from second option. – Arash Aug 17 '19 at 17:48
  • 1
    @Arash Maybe you might be interested by the examples I put on GitHub https://jmini.github.io/jdt-experiments/#programcreek-examples. I run JDT code inside JUnit-Test and I have separated the examples in 2 categories: standalone vs requiring osgi – Jmini Jan 18 '20 at 12:23