/* * 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.lang.psi.impl.resolve; import java.util.List; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import consulo.annotations.RequiredReadAction; import consulo.csharp.lang.psi.CSharpConstructorDeclaration; import consulo.csharp.lang.psi.CSharpConversionMethodDeclaration; import consulo.csharp.lang.psi.CSharpIndexMethodDeclaration; import consulo.csharp.lang.psi.CSharpMethodDeclaration; import consulo.csharp.lang.psi.resolve.CSharpElementGroup; import consulo.csharp.lang.psi.resolve.CSharpResolveContext; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.UserDataHolder; import com.intellij.psi.PsiElement; import com.intellij.psi.tree.IElementType; import com.intellij.util.ArrayUtil; import com.intellij.util.Processor; import com.intellij.util.SmartList; import consulo.csharp.lang.CSharpCastType; /** * @author VISTALL * @since 07.10.14 */ public class CSharpCompositeResolveContext implements CSharpResolveContext { private final Project myProject; private final CSharpResolveContext[] myContexts; public CSharpCompositeResolveContext(Project project, CSharpResolveContext... contexts) { myProject = project; myContexts = contexts; } @RequiredReadAction @Nullable @Override public CSharpElementGroup<CSharpIndexMethodDeclaration> indexMethodGroup(boolean deep) { List<CSharpElementGroup<CSharpIndexMethodDeclaration>> groups = new SmartList<CSharpElementGroup<CSharpIndexMethodDeclaration>>(); for(CSharpResolveContext context : myContexts) { CSharpElementGroup<CSharpIndexMethodDeclaration> elementGroup = context.indexMethodGroup(deep); if(elementGroup != null) { groups.add(elementGroup); } } return groups.isEmpty() ? null : new CSharpCompositeElementGroupImpl<CSharpIndexMethodDeclaration>(myProject, groups); } @RequiredReadAction @Nullable @Override public CSharpElementGroup<CSharpConstructorDeclaration> constructorGroup() { List<CSharpElementGroup<CSharpConstructorDeclaration>> groups = new SmartList<CSharpElementGroup<CSharpConstructorDeclaration>>(); for(CSharpResolveContext context : myContexts) { CSharpElementGroup<CSharpConstructorDeclaration> elementGroup = context.constructorGroup(); if(elementGroup != null) { groups.add(elementGroup); } } return groups.isEmpty() ? null : new CSharpCompositeElementGroupImpl<CSharpConstructorDeclaration>(myProject, groups); } @RequiredReadAction @Nullable @Override public CSharpElementGroup<CSharpConstructorDeclaration> deConstructorGroup() { List<CSharpElementGroup<CSharpConstructorDeclaration>> groups = new SmartList<CSharpElementGroup<CSharpConstructorDeclaration>>(); for(CSharpResolveContext context : myContexts) { CSharpElementGroup<CSharpConstructorDeclaration> elementGroup = context.deConstructorGroup(); if(elementGroup != null) { groups.add(elementGroup); } } return groups.isEmpty() ? null : new CSharpCompositeElementGroupImpl<CSharpConstructorDeclaration>(myProject, groups); } @RequiredReadAction @Nullable @Override public CSharpElementGroup<CSharpMethodDeclaration> findOperatorGroupByTokenType(@NotNull IElementType type, boolean deep) { List<CSharpElementGroup<CSharpMethodDeclaration>> groups = new SmartList<CSharpElementGroup<CSharpMethodDeclaration>>(); for(CSharpResolveContext context : myContexts) { CSharpElementGroup<CSharpMethodDeclaration> elementGroup = context.findOperatorGroupByTokenType(type, deep); if(elementGroup != null) { groups.add(elementGroup); } } return groups.isEmpty() ? null : new CSharpCompositeElementGroupImpl<CSharpMethodDeclaration>(myProject, groups); } @RequiredReadAction @Nullable @Override public CSharpElementGroup<CSharpConversionMethodDeclaration> findConversionMethodGroup(@NotNull CSharpCastType castType, boolean deep) { List<CSharpElementGroup<CSharpConversionMethodDeclaration>> groups = new SmartList<CSharpElementGroup<CSharpConversionMethodDeclaration>>(); for(CSharpResolveContext context : myContexts) { CSharpElementGroup<CSharpConversionMethodDeclaration> elementGroup = context.findConversionMethodGroup(castType, deep); if(elementGroup != null) { groups.add(elementGroup); } } return groups.isEmpty() ? null : new CSharpCompositeElementGroupImpl<CSharpConversionMethodDeclaration>(myProject, groups); } @RequiredReadAction @Nullable @Override public CSharpElementGroup<CSharpMethodDeclaration> findExtensionMethodGroupByName(@NotNull String name) { List<CSharpElementGroup<CSharpMethodDeclaration>> groups = new SmartList<CSharpElementGroup<CSharpMethodDeclaration>>(); for(CSharpResolveContext context : myContexts) { CSharpElementGroup<CSharpMethodDeclaration> elementGroup = context.findExtensionMethodGroupByName(name); if(elementGroup != null) { groups.add(elementGroup); } } return groups.isEmpty() ? null : new CSharpCompositeElementGroupImpl<CSharpMethodDeclaration>(myProject, groups); } @RequiredReadAction @Override public boolean processExtensionMethodGroups(@NotNull Processor<CSharpElementGroup<CSharpMethodDeclaration>> processor) { for(CSharpResolveContext context : myContexts) { if(!context.processExtensionMethodGroups(processor)) { return false; } } return true; } @RequiredReadAction @NotNull @Override public PsiElement[] findByName(@NotNull String name, boolean deep, @NotNull UserDataHolder holder) { PsiElement[] array = PsiElement.EMPTY_ARRAY; for(CSharpResolveContext context : myContexts) { PsiElement[] byName = context.findByName(name, deep, holder); array = ArrayUtil.mergeArrays(array, byName); } return array; } @RequiredReadAction @Override public boolean processElements(@NotNull Processor<PsiElement> processor, boolean deep) { for(CSharpResolveContext context : myContexts) { ProgressManager.checkCanceled(); if(!context.processElements(processor, deep)) { return false; } } return true; } @NotNull @Override public PsiElement getElement() { throw new IllegalArgumentException("Composite context"); } @NotNull public CSharpResolveContext[] getContexts() { return myContexts; } }