package com.haskforce.highlighting.annotation.external;
import com.haskforce.settings.ToolKey;
import com.haskforce.utils.ExecUtil;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.VisualPosition;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiUtilBase;
/**
* This class will return the type info of the type under cursor or the selection. It seems to be necessary
* to correct the positions under cursor. IntelliJ treats the 'origin' position of a file as (0,0). GhcMod treats
* files as (1,1) based.
* Effectively, this means that if IntelliJ reports the selection as being (2,1), for GhcMod
* it should be corrected to (3,2).
* <p/>
* Next to this offset correction, this class just calls GhcMod and returns the type info. In case no type info can be found
* it will report the error encountered instead of the type info.
*/
public class TypeInfoUtil {
public static String getTypeInfo(Project project) {
FileEditorManager fileEditorManager = FileEditorManager.getInstance(
project);
if (fileEditorManager == null){
return null;
}
Editor textEditor = fileEditorManager.getSelectedTextEditor();
if (textEditor == null){
return null;
}
VisualPosition blockStart = correctFor0BasedVS1Based(textEditor.getSelectionModel().getSelectionStartPosition());
VisualPosition blockEnd = correctFor0BasedVS1Based(textEditor.getSelectionModel().getSelectionEndPosition());
if (blockStart == null || blockEnd == null){
return null;
}
PsiFile psiFileInEditor = PsiUtilBase.getPsiFileInEditor(textEditor, project);
if(psiFileInEditor == null){
return "no psi file found";
}
VirtualFile projectFile = psiFileInEditor.getVirtualFile();
if (projectFile == null){
return "project file is null";
}
Module module = ModuleUtilCore.findModuleForFile(projectFile, project);
return getTypeInfo(module, blockStart, blockEnd, projectFile);
}
public static String getTypeInfo(Module module, VisualPosition blockStart, VisualPosition blockEnd, VirtualFile projectFile) {
final String canonicalPath = projectFile.getCanonicalPath();
if (canonicalPath == null){
return "canonical path is null";
}
final String workDir = ExecUtil.guessWorkDir(module);
if (ToolKey.GHC_MODI_KEY.getPath(module.getProject()) != null) {
GhcModi ghcModi = module.getComponent(GhcModi.class);
if (ghcModi != null) {
return GhcModi.getFutureType(module.getProject(), ghcModi.type(canonicalPath,
blockStart, blockEnd));
} else {
return "ghcModi is not configured";
}
} else {
return GhcMod.type(module, workDir, canonicalPath, blockStart, blockEnd);
}
}
public static VisualPosition correctFor0BasedVS1Based(VisualPosition pos0Based) {
if (pos0Based == null){
return null;
}
return new VisualPosition(pos0Based.line+1,pos0Based.column+1);
}
}