/*
* Copyright 2013 Guidewire Software, Inc.
*/
package gw.plugin.ij.lang.parser;
import com.intellij.lang.annotation.AnnotationHolder;
import com.intellij.lang.annotation.Annotator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import gw.lang.reflect.IProvidesCustomErrorInfo;
import gw.lang.reflect.IType;
import gw.lang.reflect.TypeSystem;
import gw.lang.reflect.module.IModule;
import gw.plugin.ij.util.FileUtil;
import gw.plugin.ij.util.GosuModuleUtil;
import gw.plugin.ij.util.TypeUtil;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
import java.util.WeakHashMap;
public class GosuOpenTypeAnnotator implements Annotator, Condition<VirtualFile> {
private static final Map<Project, GosuOpenTypeAnnotator> INSTANCES = new WeakHashMap<>();
private final Project _project;
public static GosuOpenTypeAnnotator instance( Project project ) {
GosuOpenTypeAnnotator instance = INSTANCES.get( project );
if( instance == null ) {
INSTANCES.put( project, instance = new GosuOpenTypeAnnotator( project ) );
}
return instance;
}
public GosuOpenTypeAnnotator( Project project ) {
_project = project;
}
@Override
public void annotate(@NotNull PsiElement psiElement, @NotNull AnnotationHolder annotationHolder) {
final PsiFile psiFile = psiElement.getContainingFile();
if (psiFile != null) {
final VirtualFile virtualFile = psiFile.getVirtualFile();
if (virtualFile != null) {
final IModule module = GosuModuleUtil.findModuleForPsiElement(psiElement);
if (module != null) {
TypeSystem.pushModule(module);
try {
final String[] types = TypeSystem.getTypesForFile(module, FileUtil.toIFile(virtualFile));
for (String typeName : types) {
IType type = TypeSystem.getByFullNameIfValid(typeName);
if (type instanceof IProvidesCustomErrorInfo) {
for (IProvidesCustomErrorInfo.CustomErrorInfo info : ((IProvidesCustomErrorInfo) type).getCustomErrors()) {
final IProvidesCustomErrorInfo.ErrorLevel level = info.getLevel();
final TextRange range = new TextRange(info.getStart(), info.getEnd());
final String message = info.getMessage();
if (level == IProvidesCustomErrorInfo.ErrorLevel.ERROR) {
annotationHolder.createErrorAnnotation(range, message);
} else if (level == IProvidesCustomErrorInfo.ErrorLevel.WARNING) {
annotationHolder.createWarningAnnotation(range, message);
} else if (level == IProvidesCustomErrorInfo.ErrorLevel.INFO) {
annotationHolder.createInfoAnnotation(range, message);
}
}
}
}
} finally {
TypeSystem.popModule(module);
}
}
}
}
}
@Override
public boolean value(VirtualFile file) {
return !TypeUtil.getTypesForFile(GosuModuleUtil.getGlobalModule(_project), file).isEmpty();
}
}