Less yellow code.
[idea/community.git] / platform / lang-impl / src / com / intellij / ide / actions / RelatedItemLineMarkerGotoAdapter.java
1 /*
2  * Copyright 2000-2011 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.ide.actions;
17
18 import com.intellij.codeInsight.daemon.LineMarkerProvider;
19 import com.intellij.codeInsight.daemon.RelatedItemLineMarkerInfo;
20 import com.intellij.codeInsight.daemon.RelatedItemLineMarkerProvider;
21 import com.intellij.codeInsight.daemon.impl.LineMarkersPass;
22 import com.intellij.navigation.GotoRelatedItem;
23 import com.intellij.navigation.GotoRelatedProvider;
24 import com.intellij.psi.PsiElement;
25 import com.intellij.psi.PsiFile;
26 import com.intellij.util.containers.ContainerUtil;
27 import org.jetbrains.annotations.NotNull;
28
29 import java.util.*;
30
31 /**
32  * @author nik
33  */
34 public class RelatedItemLineMarkerGotoAdapter extends GotoRelatedProvider {
35   @NotNull
36   @Override
37   public List<? extends GotoRelatedItem> getItems(@NotNull PsiElement context) {
38     List<PsiElement> parents = new ArrayList<PsiElement>();
39     PsiElement current = context;
40     while (current != null) {
41       parents.add(current);
42       if (current instanceof PsiFile) break;
43       current = current.getParent();
44     }
45
46     List<LineMarkerProvider> providers = LineMarkersPass.getMarkerProviders(context.getLanguage(), context.getProject());
47     List<GotoRelatedItem> items = new ArrayList<GotoRelatedItem>();
48     for (LineMarkerProvider provider : providers) {
49       if (provider instanceof RelatedItemLineMarkerProvider) {
50         List<RelatedItemLineMarkerInfo> markers = new ArrayList<RelatedItemLineMarkerInfo>();
51         RelatedItemLineMarkerProvider relatedItemLineMarkerProvider = (RelatedItemLineMarkerProvider)provider;
52         for (PsiElement parent : parents) {
53           ContainerUtil.addIfNotNull(relatedItemLineMarkerProvider.getLineMarkerInfo(parent), markers);
54         }
55         relatedItemLineMarkerProvider.collectNavigationMarkers(parents, markers, true);
56
57         addItemsForMarkers(markers, items);
58       }
59     }
60
61     return items;
62   }
63
64   private static void addItemsForMarkers(List<RelatedItemLineMarkerInfo> markers,
65                                          List<GotoRelatedItem> result) {
66     Set<PsiFile> addedFiles = new HashSet<PsiFile>();
67     for (RelatedItemLineMarkerInfo<?> marker : markers) {
68       Collection<? extends GotoRelatedItem> items = marker.createGotoRelatedItems();
69       for (GotoRelatedItem item : items) {
70         PsiElement element = item.getElement();
71         if (element instanceof PsiFile) {
72           PsiFile file = (PsiFile)element;
73           if (addedFiles.contains(file)) {
74             continue;
75           }
76         }
77         if (element != null) {
78           ContainerUtil.addIfNotNull(element.getContainingFile(), addedFiles);
79         }
80         result.add(item);
81       }
82     }
83   }
84 }