KT-4909 Smart completion does not work for named arguments

KT-7668 Named argument completion does not work after vararg

 #KT-4909 Fixed
 #KT-7668 Fixed
This commit is contained in:
Valentin Kipyatkov
2015-05-07 19:48:52 +03:00
parent 58ac497bd7
commit 67cfd9d516
45 changed files with 474 additions and 215 deletions
@@ -0,0 +1,65 @@
/*
* Copyright 2010-2015 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 org.jetbrains.kotlin.idea.core
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.psi.Call
import org.jetbrains.kotlin.psi.FunctionLiteralArgument
import org.jetbrains.kotlin.psi.ValueArgument
import java.util.HashMap
public fun Call.mapArgumentsToParameters(targetDescriptor: CallableDescriptor): Map<ValueArgument, ValueParameterDescriptor> {
val parameters = targetDescriptor.getValueParameters()
if (parameters.isEmpty()) return emptyMap()
val map = HashMap<ValueArgument, ValueParameterDescriptor>()
val parametersByName = parameters.toMap { it.getName().asString() }
var positionalArgumentIndex: Int? = 0
for (argument in getValueArguments()) {
if (argument is FunctionLiteralArgument) {
map[argument] = parameters.last()
}
else {
val argumentName = argument.getArgumentName()?.getReferenceExpression()?.getReferencedName()
if (argumentName != null) {
if (targetDescriptor.hasStableParameterNames()) {
val parameter = parametersByName[argumentName]
if (parameter != null) {
map[argument] = parameter
}
}
positionalArgumentIndex = null
}
else {
if (positionalArgumentIndex != null && positionalArgumentIndex < parameters.size()) {
val parameter = parameters[positionalArgumentIndex]
map[argument] = parameter
if (parameter.getVarargElementType() == null || argument.getSpreadElement() != null) {
positionalArgumentIndex++
}
}
}
}
}
return map
}
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.idea.core.quickfix;
import com.google.common.collect.Sets;
import com.intellij.extapi.psi.ASTDelegatePsiElement;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
@@ -24,10 +23,8 @@ import com.intellij.psi.PsiWhiteSpace;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.ReadOnly;
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
import org.jetbrains.kotlin.diagnostics.Diagnostic;
import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage;
import org.jetbrains.kotlin.idea.references.BuiltInsReferenceResolver;
@@ -44,8 +41,6 @@ import org.jetbrains.kotlin.types.DeferredType;
import org.jetbrains.kotlin.types.JetType;
import org.jetbrains.kotlin.types.checker.JetTypeChecker;
import java.util.Set;
public class QuickFixUtil {
private QuickFixUtil() {
}
@@ -167,39 +162,6 @@ public class QuickFixUtil {
}
}
@ReadOnly
@NotNull
public static Set<String> getUsedParameters(
@NotNull JetCallElement callElement,
@Nullable JetValueArgument ignoreArgument,
@NotNull CallableDescriptor callableDescriptor
) {
Set<String> usedParameters = Sets.newHashSet();
boolean isPositionalArgument = true;
int idx = 0;
for (ValueArgument argument : callElement.getValueArguments()) {
if (argument.isNamed()) {
JetValueArgumentName name = argument.getArgumentName();
assert name != null : "Named argument's name cannot be null";
if (argument != ignoreArgument) {
usedParameters.add(name.getText());
}
isPositionalArgument = false;
}
else if (isPositionalArgument) {
if (callableDescriptor.getValueParameters().size() > idx) {
ValueParameterDescriptor parameter = callableDescriptor.getValueParameters().get(idx);
if (argument != ignoreArgument) {
usedParameters.add(parameter.getName().asString());
}
idx++;
}
}
}
return usedParameters;
}
public static String renderTypeWithFqNameOnClash(JetType type, String nameToCheckAgainst) {
FqName typeFqName = DescriptorUtils.getFqNameSafe(DescriptorUtils.getClassDescriptorForType(type));
FqName fqNameToCheckAgainst = new FqName(nameToCheckAgainst);