How to create an IntelliJ project taht can resolve types the jdk standard library

Answered

UPDATE : I think figured it out, but will be glad to hear any comments about the way I use the platform. See solution below.

-----------------------------

ORIGINAL:

Hello,

I create an application that uses IntelliJ for its code insight and  parsing capabilities.

So I create an IdeaTestApplication instance.

I cannot get IntelliJ to figure out the paths of the JDK.

In the example, I have a field f of type List<Integer>. The type of f cannot be resolved.

I expect f.getType().getCannonicalText() to retrieve: "java.util.List<java.lang.Integer>"

But it actually is:  "List<Integer>"

I suspect that I do not setup the project's JDK properly.

I am allowed to use internal classes of IntelliJ - i.e., such that are not part of the OpenAPI.

 


import com.intellij.ide.impl.NewProjectUtil;
import com.intellij.idea.IdeaTestApplication;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.module.JavaModuleType;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ex.ProjectManagerEx;
import com.intellij.openapi.projectRoots.JavaSdk;
import com.intellij.openapi.projectRoots.ProjectJdkTable;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.SdkType;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.search.FilenameIndex;
import com.intellij.testFramework.PsiTestUtil;
import org.jetbrains.annotations.NotNull;

import java.util.Objects;


public class CleanCreateProject {
private static Project createAnOpenProject(String projectName, String projectRoot) {
final ProjectManagerEx myProjectManager = ProjectManagerEx.getInstanceEx();
final Project project = myProjectManager.newProject(projectName, projectRoot, true, false);
myProjectManager.openProject(project);
return project;
}

public static void main(String[] args){
IdeaTestApplication.getInstance(null);
new WriteAction<Integer>() {
@Override
protected void run(@NotNull Result<Integer> result) {

Project project = createAnOpenProject("myProject", root());
setupJdk(project);
ModuleType moduleType = JavaModuleType.getModuleType();
Module module = ModuleManager.getInstance(project).newModule(moduleIMLPath(), moduleType.getId());
PsiTestUtil.addSourceContentToRoots(module,
Objects.requireNonNull(LocalFileSystem.getInstance().findFileByPath(srcRoot())),
false);

showProblem(project);
result.setResult(0);
}
}.execute();

}

private static void showProblem(Project project) {
for(VirtualFile virtualFile: FilenameIndex.getAllFilesByExt(project, "java")){
PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile);
for(PsiClass cls: ((PsiClassOwner)psiFile).getClasses()){
System.out.println("cls.getName() = " + cls.getName());
PsiField f = cls.findFieldByName("f", false);
System.out.println("f.getType().getCanonicalText() = " + f.getType().getCanonicalText());
}
}
}

public static void setupJdk(Project project) {
Sdk jdk = JavaSdk.getInstance().createJdk("java 1.8", jdkHomeDirectory(), false);
ProjectJdkTable.getInstance().addJdk(jdk);
ProjectRootManager.getInstance(project).setProjectSdk(jdk);
NewProjectUtil.applyJdkToProject(project, jdk);
for(SdkType t: SdkType.getAllTypes()){
assert t.getName().equals("JavaSDK");
t.setupSdkPaths(jdk);
break;
}
}

private static String jdkHomeDirectory() {
return "/usr/lib/jvm/jdk1.8.0_181";
}


private static String root() {
return "/tmp/projectRoot";
}

private static String srcRoot() {
return root() + "/src";
}

private static String moduleIMLPath() {
return root() + "/file.iml";
}
}

 

In my file system, the contents of the java file is:

import java.util.List;

class A{
        List<Integer> f;
}

 

--------------------

SOLUTION:

What I did is to setup the Jdk for each module, by adding the following lines:

Module[] modules = ModuleManager.getInstance(project).getModules();
for (Module module : modules) {
ModuleRootModificationUtil.setModuleSdk(module, jdk);
}

 

Overall, here is the working example:

package playground;


import com.intellij.ide.impl.NewProjectUtil;
import com.intellij.idea.IdeaTestApplication;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.module.JavaModuleType;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ex.ProjectManagerEx;
import com.intellij.openapi.projectRoots.JavaSdk;
import com.intellij.openapi.projectRoots.ProjectJdkTable;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ModuleRootModificationUtil;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiField;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.testFramework.PsiTestUtil;
import org.jetbrains.annotations.NotNull;

import java.util.Objects;


public class ShowProblem {
private static Project createAnOpenProject(String projectName, String projectRoot) {
final ProjectManagerEx myProjectManager = ProjectManagerEx.getInstanceEx();
final Project project = myProjectManager.newProject(projectName, projectRoot, true, false);
myProjectManager.openProject(project);
return project;
}

public static void main(String[] args){
IdeaTestApplication.getInstance(null);
new WriteAction<Integer>() {
@Override
protected void run(@NotNull Result<Integer> result) {

Project project = createAnOpenProject("myProject", root());

ModuleType moduleType = JavaModuleType.getModuleType();
Module module = ModuleManager.getInstance(project).newModule(moduleIMLPath(), moduleType.getId());
PsiTestUtil.addSourceContentToRoots(module,
Objects.requireNonNull(LocalFileSystem.getInstance().findFileByPath(srcRoot())),
false);
setupJdk(project);
showProblem(project);
result.setResult(0);
}
}.execute();

}

private static void showProblem(Project project) {
JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
PsiClass cls = facade.findClass("A", GlobalSearchScope.projectScope(project));
System.out.println("cls.getName() = " + cls.getName());
PsiField f = cls.findFieldByName("l", false);
System.out.println("f.getType().getCanonicalText() = " + f.getType().getCanonicalText());
}

public static void setupJdk(Project project) {
Sdk jdk = JavaSdk.getInstance().createJdk("java 1.8", jdkHomeDirectory(), false);
ProjectJdkTable.getInstance().addJdk(jdk);
ProjectRootManager.getInstance(project).setProjectSdk(jdk);
NewProjectUtil.applyJdkToProject(project, jdk);

Module[] modules = ModuleManager.getInstance(project).getModules();
for (Module module : modules) {
ModuleRootModificationUtil.setModuleSdk(module, jdk);
}
}

private static String jdkHomeDirectory() {
return "/usr/lib/jvm/jdk1.8.0_181";
}


private static String root() {
return "/tmp/projectRoot";
}

private static String srcRoot() {
return root() + "/src";
}

private static String moduleIMLPath() {
return root() + "/file.iml";
}
}

 

Please sign in to leave a comment.