2 * Copyright 2000-2016 JetBrains s.r.o.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org.jetbrains.plugins.groovy.codeInsight.hint
18 import com.intellij.codeInsight.hints.InlayInfo
19 import com.intellij.codeInsight.hints.InlayParameterHintsProvider
20 import com.intellij.codeInsight.hints.MethodInfo
21 import com.intellij.lang.java.JavaLanguage
22 import com.intellij.openapi.util.text.StringUtil
23 import com.intellij.psi.PsiElement
24 import com.intellij.psi.PsiMethod
25 import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument
26 import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall
27 import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod
28 import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil
30 class GroovyInlayParameterHintsProvider : InlayParameterHintsProvider {
32 private companion object {
33 val blackList = setOf(
34 "org.codehaus.groovy.runtime.DefaultGroovyMethods.*"
38 override fun getParameterHints(element: PsiElement) = (element as? GrCall)?.doGetParameterHints() ?: emptyList()
40 private fun GrCall.doGetParameterHints(): List<InlayInfo>? {
41 val signature = GrClosureSignatureUtil.createSignature(this) ?: return null
42 val infos = GrClosureSignatureUtil.mapParametersToArguments(signature, this) ?: return null
43 val original = signature.parameters.zip(infos)
45 // leave only parameters with names
46 val map = original.mapNotNull {
47 it.first.name?.let { name -> name to it.second }
50 // leave only regular arguments and varargs
51 val nonNamedArguments = map.filterValues {
52 !it.isMultiArg || it.args.none { it is GrNamedArgument }
55 return nonNamedArguments.mapNotNull {
57 info.args.firstOrNull()?.let { arg ->
58 val inlayText = if (info.isMultiArg) "...$name" else name
59 InlayInfo(inlayText, arg.textRange.startOffset)
64 override fun getMethodInfo(element: PsiElement): MethodInfo? {
65 val call = element as? GrCall
66 val resolved = call?.resolveMethod()
67 val method = (resolved as? GrGdkMethod)?.staticMethod ?: resolved
68 return method?.getMethodInfo()
71 private fun PsiMethod.getMethodInfo(): MethodInfo? {
72 val clazzName = containingClass?.qualifiedName ?: return null
73 val fullMethodName = StringUtil.getQualifiedName(clazzName, name)
74 val paramNames: List<String> = parameterList.parameters.map { it.name ?: "" }
75 return MethodInfo(fullMethodName, paramNames)
78 override val defaultBlackList: Set<String> get() = blackList
80 override fun getBlackListDependencyLanguage() = JavaLanguage.INSTANCE