/* * Copyright 2013 Guidewire Software, Inc. */ package gw.plugin.ij.view; import com.intellij.lang.Language; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiManager; import com.intellij.psi.PsiReference; import com.intellij.psi.SingleRootFileViewProvider; import com.intellij.psi.impl.source.resolve.reference.impl.PsiMultiReference; import gw.plugin.ij.lang.GosuLanguage; import gw.plugin.ij.lang.psi.impl.GosuScratchpadFileImpl; import gw.plugin.ij.lang.psi.impl.expressions.GosuNewExpressionImpl; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class GosuFileViewProvider extends SingleRootFileViewProvider { public GosuFileViewProvider(@NotNull PsiManager manager, @NotNull VirtualFile file) { super(manager, file); } public GosuFileViewProvider(@NotNull PsiManager manager, @NotNull VirtualFile virtualFile, boolean physical) { super(manager, virtualFile, physical); } protected GosuFileViewProvider(@NotNull PsiManager manager, @NotNull VirtualFile virtualFile, boolean physical, @NotNull Language language) { super(manager, virtualFile, physical, language); } @Override public PsiReference findReferenceAt(int offset) { final PsiReference ref = super.findReferenceAt(offset); return findRef(ref, offset); } @Override public PsiReference findReferenceAt(int offset, @NotNull Language language) { final PsiReference ref = super.findReferenceAt(offset, language); if (language instanceof GosuLanguage) { return findRef(ref, offset); } return ref; } public boolean isPhysical() { return super.isPhysical() || getVirtualFile().getName().startsWith(GosuScratchpadFileImpl.GOSU_SCRATCHPAD_NAME); } private PsiReference findRef(@Nullable PsiReference psiReference, int offset) { // Handle resolving constructor inside new-expression, instead of resolving the type-literal if (psiReference instanceof PsiMultiReference) { PsiReference[] refs = ((PsiMultiReference) psiReference).getReferences(); for (PsiReference ref : refs) { if (ref instanceof GosuNewExpressionImpl) { return ref; } } for (PsiReference ref : refs) { if (((PsiElement) ref).getTextRange().containsOffset(offset)) { return psiReference; } } } return psiReference; } }