6a7dfe574d6be4542270587227051f5cb2ab478c
[idea/community.git] / platform / core-impl / src / com / intellij / codeInsight / completion / CompletionUtilCoreImpl.java
1 package com.intellij.codeInsight.completion;
2
3 import com.intellij.injected.editor.DocumentWindow;
4 import com.intellij.openapi.editor.Document;
5 import com.intellij.openapi.util.TextRange;
6 import com.intellij.psi.PsiElement;
7 import com.intellij.psi.PsiFile;
8 import com.intellij.psi.util.PsiTreeUtil;
9 import org.jetbrains.annotations.NotNull;
10 import org.jetbrains.annotations.Nullable;
11
12 /**
13  * @author yole
14  */
15 public class CompletionUtilCoreImpl {
16   @Nullable
17   public static <T extends PsiElement> T getOriginalElement(@NotNull T psi) {
18     final PsiFile file = psi.getContainingFile();
19     return getOriginalElement(psi, file);
20   }
21
22   public static <T extends PsiElement> T getOriginalElement(@NotNull T psi, PsiFile containingFile) {
23     if (containingFile != null && containingFile != containingFile.getOriginalFile() && psi.getTextRange() != null) {
24       TextRange range = psi.getTextRange();
25       Integer start = range.getStartOffset();
26       Integer end = range.getEndOffset();
27       final Document document = containingFile.getViewProvider().getDocument();
28       if (document != null) {
29         Document hostDocument = document instanceof DocumentWindow ? ((DocumentWindow)document).getDelegate() : document;
30         OffsetTranslator translator = hostDocument.getUserData(OffsetTranslator.RANGE_TRANSLATION);
31         if (translator != null) {
32           if (document instanceof DocumentWindow) {
33             TextRange translated = ((DocumentWindow)document).injectedToHost(new TextRange(start, end));
34             start = translated.getStartOffset();
35             end = translated.getEndOffset();
36           }
37
38           start = translator.translateOffset(start);
39           end = translator.translateOffset(end);
40           if (start == null || end == null) {
41             return null;
42           }
43
44           if (document instanceof DocumentWindow) {
45             start = ((DocumentWindow)document).hostToInjected(start);
46             end = ((DocumentWindow)document).hostToInjected(end);
47           }
48         }
49       }
50       //noinspection unchecked
51       return (T)PsiTreeUtil.findElementOfClassAtRange(containingFile.getOriginalFile(), start, end, psi.getClass());
52     }
53
54     return psi;
55   }
56 }