[Parameter Hints Settings] extracted parameter name hints extension

This commit is contained in:
Yaroslav Lepenkin
2016-10-10 20:15:31 +03:00
parent af8db89afe
commit b77f34347f
9 changed files with 127 additions and 60 deletions
@@ -0,0 +1,50 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* 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 com.intellij.codeInsight.hints
import com.intellij.psi.PsiCallExpression
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod
class JavaInlayParameterHintsProvider : InlayParameterHintsProvider {
override fun getMethodInfo(element: PsiElement): MethodInfo? {
if (element is PsiCallExpression) {
val resolvedElement = element.resolveMethodGenerics().element
if (resolvedElement is PsiMethod) {
return getMethodInfo(resolvedElement)
}
}
return null
}
override fun getParameterHints(element: PsiElement): List<InlayInfo> {
if (element is PsiCallExpression) {
return JavaParameterHintManager(element).descriptors
}
return emptyList()
}
private fun getMethodInfo(method: PsiMethod): MethodInfo {
val qualifier = method.containingClass?.qualifiedName ?: ""
val fullMethodName = qualifier + "." + method.name
val paramNames: List<String> = method.parameterList.parameters.map { it.name ?: "" }
return MethodInfo(fullMethodName, paramNames)
}
}
@@ -13,9 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight.daemon.impl;
package com.intellij.codeInsight.hints;
import com.intellij.codeInsight.hints.filtering.Matcher;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.TypeConversionUtil;
@@ -26,15 +25,12 @@ import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
public class ParameterNameHintsManager {
public class JavaParameterHintManager {
@NotNull
private final List<InlayInfo> myDescriptors;
private final List<Matcher> myBlackListMatchers;
public ParameterNameHintsManager(@NotNull PsiCallExpression callExpression, List<Matcher> blackListMatchers) {
myBlackListMatchers = blackListMatchers;
public JavaParameterHintManager(@NotNull PsiCallExpression callExpression) {
PsiExpression[] callArguments = getArguments(callExpression);
JavaResolveResult resolveResult = callExpression.resolveMethodGenerics();
@@ -51,14 +47,11 @@ public class ParameterNameHintsManager {
myDescriptors = descriptors;
}
private boolean isMethodToShowParams(@NotNull PsiCallExpression callExpression, @NotNull JavaResolveResult resolveResult) {
private static boolean isMethodToShowParams(@NotNull PsiCallExpression callExpression, @NotNull JavaResolveResult resolveResult) {
PsiElement element = resolveResult.getElement();
if (element instanceof PsiMethod) {
PsiMethod method = (PsiMethod)element;
if (isSetter(method) || isBuilder(callExpression, method)) {
return false;
}
return !isBlackListed(method);
return !isSetter(method) && !isBuilder(callExpression, method);
}
return false;
}
@@ -80,21 +73,6 @@ public class ParameterNameHintsManager {
return method.getParameterList().getParametersCount() == 1;
}
public static MethodInfo getMethodInfo(PsiMethod method) {
PsiClass aClass = method.getContainingClass();
String qualifier = aClass != null ? aClass.getQualifiedName() : "";
String fullMethodName = qualifier + "." + method.getName();
PsiParameter[] params = method.getParameterList().getParameters();
List<String> paramNames = ContainerUtil.map(params, (e) -> e.getName());
return new MethodInfo(fullMethodName, paramNames);
}
private boolean isBlackListed(PsiMethod method) {
MethodInfo info = getMethodInfo(method);
return myBlackListMatchers.stream().anyMatch((e) -> e.isMatching(info.getFullyQualifiedName(), info.getParamNames()));
}
private static boolean isSetter(PsiMethod method) {
String methodName = method.getName();
@@ -156,7 +134,7 @@ public class ParameterNameHintsManager {
@NotNull
private static InlayInfo createInlayInfo(@NotNull PsiExpression callArgument, @NotNull PsiParameter methodParam) {
String paramName = ((methodParam.getType() instanceof PsiEllipsisType) ? "..." : "") + methodParam.getName();
return new InlayInfo(paramName, callArgument.getTextRange().getStartOffset(), callArgument);
return new InlayInfo(paramName, callArgument.getTextRange().getStartOffset());
}
private static boolean shouldInlineParameterName(@NotNull PsiExpression argument,
@@ -0,0 +1,34 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* 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 com.intellij.codeInsight.hints
import com.intellij.lang.LanguageExtension
import com.intellij.psi.PsiElement
object InlayParameterHintsExtension: LanguageExtension<InlayParameterHintsProvider>("com.intellij.parameterHintsProvider")
interface InlayParameterHintsProvider {
fun getParameterHints(element: PsiElement): List<InlayInfo> {
return emptyList()
}
fun getMethodInfo(element: PsiElement): MethodInfo? {
return null
}
}
@@ -13,10 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight.daemon.impl
package com.intellij.codeInsight.hints
import com.intellij.psi.PsiExpression
class InlayInfo(val text: String, val offset: Int, val argument: PsiExpression)
class InlayInfo(val text: String, val offset: Int)
class MethodInfo(val fullyQualifiedName: String, val paramNames: List<String>)
@@ -13,12 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight.daemon.impl;
package com.intellij.codeInsight.hints;
import com.intellij.codeHighlighting.EditorBoundHighlightingPass;
import com.intellij.codeHighlighting.TextEditorHighlightingPass;
import com.intellij.codeHighlighting.TextEditorHighlightingPassFactory;
import com.intellij.codeHighlighting.TextEditorHighlightingPassRegistrar;
import com.intellij.codeInsight.daemon.impl.ParameterHintsPresentationManager;
import com.intellij.codeInsight.hints.filtering.Matcher;
import com.intellij.codeInsight.hints.filtering.MatcherConstructor;
import com.intellij.codeInsight.hints.settings.ParameterNameHintsSettings;
@@ -31,7 +32,9 @@ import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.psi.*;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.SyntaxTraverser;
import com.intellij.util.containers.HashSet;
import gnu.trove.TIntObjectHashMap;
import org.jetbrains.annotations.NotNull;
@@ -65,8 +68,10 @@ public class ParameterHintsPassFactory extends AbstractProjectComponent implemen
public void doCollectInformation(@NotNull ProgressIndicator progress) {
assert myDocument != null;
myAnnotations.clear();
if (!isEnabled() || !(myFile instanceof PsiJavaFile)) return;
PsiJavaFile file = (PsiJavaFile) myFile;
if (!isEnabled()) return;
InlayParameterHintsProvider provider = InlayParameterHintsExtension.INSTANCE.forLanguage(myFile.getLanguage());
if (provider == null) return;
List<Matcher> matchers = ParameterNameHintsSettings
.getInstance()
@@ -75,20 +80,21 @@ public class ParameterHintsPassFactory extends AbstractProjectComponent implemen
.map((item) -> MatcherConstructor.INSTANCE.createMatcher(item))
.collect(Collectors.toList());
SyntaxTraverser.psiTraverser(file).forEach(element -> process(element, matchers));
SyntaxTraverser.psiTraverser(myFile).forEach(element -> process(element, provider, matchers));
}
private static boolean isEnabled() {
return EditorSettingsExternalizable.getInstance().isShowParameterNameHints();
}
private void process(PsiElement child, List<Matcher> matchers) {
if (child instanceof PsiCallExpression) {
PsiCallExpression callExpression = (PsiCallExpression)child;
ParameterNameHintsManager manager = new ParameterNameHintsManager(callExpression, matchers);
for (InlayInfo info : manager.getDescriptors()) {
myAnnotations.put(info.getOffset(), info.getText());
}
private static boolean isMatchedByAny(MethodInfo info, List<Matcher> matchers) {
return matchers.stream().anyMatch((e) -> e.isMatching(info.getFullyQualifiedName(), info.getParamNames()));
}
private void process(PsiElement element, InlayParameterHintsProvider provider, List<Matcher> blackListMatchers) {
MethodInfo info = provider.getMethodInfo(element);
if (info != null && !isMatchedByAny(info, blackListMatchers)) {
provider.getParameterHints(element).forEach((h) -> myAnnotations.put(h.getOffset(), h.getText()));
}
}
@@ -13,15 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight.daemon.impl
package com.intellij.codeInsight.hints
import com.intellij.codeInsight.hints.settings.ParameterNameHintsConfigurable
import com.intellij.codeInsight.hints.settings.ParameterNameHintsSettings
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.psi.PsiCallExpression
import com.intellij.psi.PsiMethod
import com.intellij.psi.util.PsiTreeUtil
class ShowParameterHintsSettings : AnAction() {
@@ -31,7 +29,7 @@ class ShowParameterHintsSettings : AnAction() {
presentation.text = "Show Settings"
presentation.description = "Show Parameter Name Hints Settings"
}
override fun actionPerformed(e: AnActionEvent) {
val project = CommonDataKeys.PROJECT.getData(e.dataContext) ?: return
val dialog = ParameterNameHintsConfigurable(project)
@@ -55,14 +53,13 @@ class BlacklistCurrentMethodAction : AnAction() {
val offset = editor.caretModel.offset
val element = file.findElementAt(offset)
val callExpression = PsiTreeUtil.getParentOfType(element, PsiCallExpression::class.java)
val hintsProvider = InlayParameterHintsExtension.forLanguage(file.language) ?: return
val result = callExpression?.resolveMethodGenerics()?.element ?: return
if (result is PsiMethod) {
val info = ParameterNameHintsManager.getMethodInfo(result)
val pattern = info.fullyQualifiedName + '(' + info.paramNames.joinToString(",") + ')'
ParameterNameHintsSettings.getInstance().addIgnorePattern(pattern)
}
val method = PsiTreeUtil.findFirstParent(element, { e -> hintsProvider.getMethodInfo(e) != null }) ?: return
val info = hintsProvider.getMethodInfo(method) ?: return
val pattern = info.fullyQualifiedName + '(' + info.paramNames.joinToString(",") + ')'
ParameterNameHintsSettings.getInstance().addIgnorePattern(pattern)
}
}
}
@@ -576,6 +576,9 @@
<extensionPoint name="codeInsight.parameterInfo" beanClass="com.intellij.lang.LanguageExtensionPoint">
<with attribute="implementationClass" implements="com.intellij.lang.parameterInfo.ParameterInfoHandler"/>
</extensionPoint>
<extensionPoint name="parameterHintsProvider" beanClass="com.intellij.lang.LanguageExtensionPoint">
<with attribute="implementationClass" implements="com.intellij.codeInsight.hints.InlayParameterHintsProvider"/>
</extensionPoint>
<extensionPoint name="codeInsight.typeInfo" beanClass="com.intellij.lang.LanguageExtensionPoint">
<with attribute="implementationClass" implements="com.intellij.lang.ExpressionTypeProvider"/>
</extensionPoint>
@@ -300,8 +300,8 @@
</group>
<group id="ParameterNameHints" popup="true">
<action id="BlacklistCurrentMethodAction" class="com.intellij.codeInsight.daemon.impl.BlacklistCurrentMethodAction"/>
<action id="ShowParameterHintsSettings" class="com.intellij.codeInsight.daemon.impl.ShowParameterHintsSettings"/>
<action id="BlacklistCurrentMethodAction" class="com.intellij.codeInsight.hints.BlacklistCurrentMethodAction"/>
<action id="ShowParameterHintsSettings" class="com.intellij.codeInsight.hints.ShowParameterHintsSettings"/>
<action id="ToggleInlineHintsAction" class="com.intellij.analysis.actions.ToggleInlineHintsAction"/>
</group>
+2 -1
View File
@@ -71,7 +71,7 @@
<implementation-class>com.intellij.execution.scratch.JavaScratchCompilationSupport</implementation-class>
</component>
<component>
<implementation-class>com.intellij.codeInsight.daemon.impl.ParameterHintsPassFactory</implementation-class>
<implementation-class>com.intellij.codeInsight.hints.ParameterHintsPassFactory</implementation-class>
<skipForDefaultProject/>
</component>
</project-components>
@@ -1149,6 +1149,7 @@
<lang.foldingBuilder language="JAVA" implementationClass="com.intellij.codeInsight.folding.impl.JavaFoldingBuilder"/>
<parameterHintsProvider language="JAVA" implementationClass="com.intellij.codeInsight.hints.JavaInlayParameterHintsProvider"/>
<codeInsight.parameterInfo language="JAVA" implementationClass="com.intellij.codeInsight.hint.api.impls.MethodParameterInfoHandler"/>
<codeInsight.parameterInfo language="JAVA" implementationClass="com.intellij.codeInsight.hint.api.impls.ReferenceParameterInfoHandler"/>
<codeInsight.parameterInfo language="JAVA"