/* * 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.completion; import java.util.Locale; import java.util.Map; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import consulo.csharp.ide.completion.util.SpaceInsertHandler; import consulo.csharp.lang.psi.CSharpReferenceExpression; import consulo.csharp.lang.psi.CSharpTokens; import consulo.csharp.lang.psi.impl.source.CSharpPsiUtilImpl; import com.intellij.codeInsight.completion.CompletionParameters; import com.intellij.codeInsight.completion.CompletionResultSet; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.TokenSet; import com.intellij.util.containers.ConcurrentFactoryMap; import consulo.dotnet.resolve.DotNetNamespaceAsElement; import consulo.util.NotNullPairFunction; /** * @author VISTALL * @since 12.06.14 */ public class CSharpCompletionUtil { public static NotNullPairFunction<LookupElementBuilder, IElementType, LookupElement> ourSpaceInsert = new NotNullPairFunction<LookupElementBuilder, IElementType, LookupElement>() { @NotNull @Override public LookupElement fun(LookupElementBuilder lookupElementBuilder, IElementType iElementType) { lookupElementBuilder = lookupElementBuilder.withInsertHandler(SpaceInsertHandler.INSTANCE); return lookupElementBuilder; } }; private static Map<IElementType, String> ourCache = new ConcurrentFactoryMap<IElementType, String>() { @Nullable @Override protected String create(IElementType elementType) { if(elementType == CSharpTokens.NULL_LITERAL) { return "null"; } return elementType.toString().replace("_KEYWORD", "").toLowerCase(Locale.US); } }; public static final Key<IElementType> KEYWORD_ELEMENT_TYPE = Key.create("csharp.keyword.element.type"); public static boolean mayStartClassName(CompletionResultSet result) { return StringUtil.isNotEmpty(result.getPrefixMatcher().getPrefix()); } public static boolean isClassNamePossible(CompletionParameters parameters) { PsiElement position = parameters.getPosition(); if(position.getNode().getElementType() == CSharpTokens.IDENTIFIER) { PsiElement parent = position.getParent(); if(parent instanceof CSharpReferenceExpression) { if(((CSharpReferenceExpression) parent).getQualifier() != null) { return false; } CSharpReferenceExpression.ResolveToKind kind = ((CSharpReferenceExpression) parent).kind(); if(kind == CSharpReferenceExpression.ResolveToKind.TYPE_LIKE || kind == CSharpReferenceExpression.ResolveToKind.CONSTRUCTOR || kind == CSharpReferenceExpression.ResolveToKind.EXPRESSION_OR_TYPE_LIKE || kind == CSharpReferenceExpression.ResolveToKind.ANY_MEMBER) { return true; } } } return false; } public static boolean isTypeLikeElementWithNamespace(@NotNull PsiElement element) { return CSharpPsiUtilImpl.isTypeLikeElement(element) || element instanceof DotNetNamespaceAsElement; } @NotNull public static String textOfKeyword(IElementType elementType) { String firstElement = ourCache.get(elementType); assert firstElement != null; return firstElement; } public static void tokenSetToLookup(@NotNull CompletionResultSet resultSet, @NotNull TokenSet tokenSet, @Nullable NotNullPairFunction<LookupElementBuilder, IElementType, LookupElement> decorator, @Nullable Condition<IElementType> condition) { for(IElementType elementType : tokenSet.getTypes()) { elementToLookup(resultSet, elementType, decorator, condition); } } public static void elementToLookup(@NotNull CompletionResultSet resultSet, @NotNull IElementType elementType, @Nullable NotNullPairFunction<LookupElementBuilder, IElementType, LookupElement> decorator, @Nullable Condition<IElementType> condition) { if(condition != null && !condition.value(elementType)) { return; } String keyword = ourCache.get(elementType); LookupElementBuilder builder = LookupElementBuilder.create(elementType, keyword); builder = builder.bold(); LookupElement item = builder; if(decorator != null) { item = decorator.fun(builder, elementType); } item.putUserData(KEYWORD_ELEMENT_TYPE, elementType); resultSet.addElement(item); } }