/* * Copyright 2013-2017 consulo.io * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package consulo.csharp.ide; import java.util.Collection; import java.util.List; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import consulo.annotations.RequiredReadAction; import consulo.csharp.ide.lineMarkerProvider.HidedOrOverridedElementCollector; import consulo.csharp.ide.lineMarkerProvider.HidingOrOverridingElementCollector; import consulo.csharp.ide.lineMarkerProvider.LambdaLineMarkerCollector; import consulo.csharp.ide.lineMarkerProvider.LineMarkerCollector; import consulo.csharp.ide.lineMarkerProvider.OverrideTypeCollector; import consulo.csharp.ide.lineMarkerProvider.PartialTypeCollector; import consulo.csharp.ide.lineMarkerProvider.RecursiveCallCollector; import consulo.dotnet.psi.DotNetMemberOwner; import consulo.dotnet.psi.DotNetQualifiedElement; import com.intellij.codeHighlighting.Pass; import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings; import com.intellij.codeInsight.daemon.LineMarkerInfo; import com.intellij.codeInsight.daemon.LineMarkerProvider; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.colors.CodeInsightColors; import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.colors.EditorColorsScheme; import com.intellij.openapi.editor.markup.GutterIconRenderer; import com.intellij.openapi.editor.markup.SeparatorPlacement; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.util.Ref; import com.intellij.psi.PsiElement; import com.intellij.util.ArrayUtil; import com.intellij.util.Consumer; import com.intellij.util.FunctionUtil; /** * @author VISTALL * @since 29.12.13. */ public class CSharpLineMarkerProvider implements LineMarkerProvider, DumbAware { private static final LineMarkerCollector[] ourSingleCollector = { new LambdaLineMarkerCollector() }; private static final LineMarkerCollector[] ourCollectors = { new OverrideTypeCollector(), new PartialTypeCollector(), new HidingOrOverridingElementCollector(), new HidedOrOverridedElementCollector(), new RecursiveCallCollector() }; protected final DaemonCodeAnalyzerSettings myDaemonCodeAnalyzerSettings; protected final EditorColorsManager myEditorColorsManager; public CSharpLineMarkerProvider(DaemonCodeAnalyzerSettings daemonSettings, EditorColorsManager colorsManager) { myDaemonCodeAnalyzerSettings = daemonSettings; myEditorColorsManager = colorsManager; } @RequiredReadAction @Nullable @Override public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement element) { if(myDaemonCodeAnalyzerSettings.SHOW_METHOD_SEPARATORS && (element instanceof DotNetQualifiedElement)) { if(element.getNode().getTreeParent() == null) { return null; } final PsiElement parent = element.getParent(); if(!(parent instanceof DotNetMemberOwner)) { return null; } if(ArrayUtil.getFirstElement(((DotNetMemberOwner) parent).getMembers()) == element) { return null; } LineMarkerInfo info = new LineMarkerInfo<PsiElement>(element, element.getTextRange(), null, Pass.UPDATE_ALL, FunctionUtil.<Object, String>nullConstant(), null, GutterIconRenderer.Alignment.RIGHT); EditorColorsScheme scheme = myEditorColorsManager.getGlobalScheme(); info.separatorColor = scheme.getColor(CodeInsightColors.METHOD_SEPARATORS_COLOR); info.separatorPlacement = SeparatorPlacement.TOP; return info; } final Ref<LineMarkerInfo> ref = Ref.create(); Consumer<LineMarkerInfo> consumer = new Consumer<LineMarkerInfo>() { @Override public void consume(LineMarkerInfo markerInfo) { ref.set(markerInfo); } }; //noinspection ForLoopReplaceableByForEach for(int j = 0; j < ourSingleCollector.length; j++) { LineMarkerCollector ourCollector = ourSingleCollector[j]; ourCollector.collect(element, consumer); } return ref.get(); } @RequiredReadAction @Override public void collectSlowLineMarkers(@NotNull List<PsiElement> elements, @NotNull final Collection<LineMarkerInfo> lineMarkerInfos) { ApplicationManager.getApplication().assertReadAccessAllowed(); if(elements.isEmpty() || DumbService.getInstance(elements.get(0).getProject()).isDumb()) { return; } Consumer<LineMarkerInfo> consumer = new Consumer<LineMarkerInfo>() { @Override public void consume(LineMarkerInfo lineMarkerInfo) { lineMarkerInfos.add(lineMarkerInfo); } }; //noinspection ForLoopReplaceableByForEach for(int i = 0; i < elements.size(); i++) { PsiElement psiElement = elements.get(i); //noinspection ForLoopReplaceableByForEach for(int j = 0; j < ourCollectors.length; j++) { LineMarkerCollector ourCollector = ourCollectors[j]; ourCollector.collect(psiElement, consumer); } } } }