Create from usage: Fixed duplication of type parameters.

This commit is contained in:
Jack Zhou
2013-04-11 10:00:40 -04:00
parent c0bbb7b2cc
commit b07548184a
@@ -320,12 +320,13 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase {
* A sort-of dummy <code>Expression</code> for parameter lists, to allow us to update the parameter list as the user makes selections. * A sort-of dummy <code>Expression</code> for parameter lists, to allow us to update the parameter list as the user makes selections.
*/ */
private static class TypeParameterListExpression extends Expression { private static class TypeParameterListExpression extends Expression {
private final String[] ownerTypeParameterNames; private final TypeParameterDescriptor[] typeParametersFromReceiverType;
private final Map<String, String[]> typeParameterMap; private final Map<String, TypeParameterDescriptor[]> typeParameterMap;
public TypeParameterListExpression(@NotNull String[] ownerTypeParameterNames, @NotNull Map<String, String[]> typeParameterMap) { public TypeParameterListExpression(@NotNull TypeParameterDescriptor[] typeParametersFromReceiverType,
this.ownerTypeParameterNames = ownerTypeParameterNames; @NotNull Map<String, TypeParameterDescriptor[]> typeParametersMap) {
this.typeParameterMap = typeParameterMap; this.typeParametersFromReceiverType = typeParametersFromReceiverType;
this.typeParameterMap = typeParametersMap;
} }
@NotNull @NotNull
@@ -343,24 +344,29 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase {
assert func != null; assert func != null;
List<JetParameter> parameters = func.getValueParameters(); List<JetParameter> parameters = func.getValueParameters();
List<String> typeParameterNames = new ArrayList<String>(); Set<TypeParameterDescriptor> typeParameters = new LinkedHashSet<TypeParameterDescriptor>();
Collections.addAll(typeParameterNames, ownerTypeParameterNames); Collections.addAll(typeParameters, typeParametersFromReceiverType);
for (JetParameter parameter : parameters) { for (JetParameter parameter : parameters) {
JetTypeReference parameterTypeRef = parameter.getTypeReference(); JetTypeReference parameterTypeRef = parameter.getTypeReference();
assert parameterTypeRef != null; assert parameterTypeRef != null;
String[] names = typeParameterMap.get(parameterTypeRef.getText()); TypeParameterDescriptor[] typeParametersFromParameter = typeParameterMap.get(parameterTypeRef.getText());
if (names != null) { if (typeParametersFromParameter != null) {
Collections.addAll(typeParameterNames, names); Collections.addAll(typeParameters, typeParametersFromParameter);
} }
} }
JetTypeReference returnTypeRef = func.getReturnTypeRef(); JetTypeReference returnTypeRef = func.getReturnTypeRef();
if (returnTypeRef != null) { if (returnTypeRef != null) {
String[] names = typeParameterMap.get(returnTypeRef.getText()); TypeParameterDescriptor[] typeParametersFromReturnType = typeParameterMap.get(returnTypeRef.getText());
if (names != null) { if (typeParametersFromReturnType != null) {
Collections.addAll(typeParameterNames, names); Collections.addAll(typeParameters, typeParametersFromReturnType);
} }
} }
List<String> typeParameterNames = new ArrayList<String>();
for (TypeParameterDescriptor typeParameter : typeParameters) {
typeParameterNames.add(typeParameter.getName().getIdentifier());
}
// make sure there are no name conflicts // make sure there are no name conflicts
for (int i = 0; i < typeParameterNames.size(); i++) { for (int i = 0; i < typeParameterNames.size(); i++) {
String name = typeParameterNames.get(i); String name = typeParameterNames.get(i);
@@ -565,9 +571,6 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase {
JetParameterList parameterList = func.getValueParameterList(); JetParameterList parameterList = func.getValueParameterList();
assert parameterList != null; assert parameterList != null;
BindingContext containingFileContext = currentFile.equals(containingFile)
? currentFileContext
: AnalyzerFacadeWithCache.analyzeFileWithCache(containingFile).getBindingContext();
JetScope scope; JetScope scope;
if (isExtension) { if (isExtension) {
NamespaceDescriptor namespaceDescriptor = currentFileContext.get(BindingContext.FILE_TO_NAMESPACE, containingFile); NamespaceDescriptor namespaceDescriptor = currentFileContext.get(BindingContext.FILE_TO_NAMESPACE, containingFile);
@@ -731,9 +734,9 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase {
@Nullable TypeExpression returnTypeExpression, @Nullable TypeExpression returnTypeExpression,
@NotNull JetScope scope @NotNull JetScope scope
) { ) {
Map<String, String[]> typeParameterMap = new HashMap<String, String[]>(); Map<String, TypeParameterDescriptor[]> typeParameterMap = new HashMap<String, TypeParameterDescriptor[]>();
Set<TypeParameterDescriptor> receiverTypeParameters = getTypeParametersInType(receiverType); Set<TypeParameterDescriptor> receiverTypeParameters = getTypeParametersInType(receiverType);
String[] ownerTypeParameterNames = getTypeParameterNamesNotInScope(receiverTypeParameters, scope); TypeParameterDescriptor[] receiverTypeParametersNotInScope = getTypeParameterNamesNotInScope(receiverTypeParameters, scope);
for (TypeExpression parameterTypeExpression : parameterTypeExpressions) { for (TypeExpression parameterTypeExpression : parameterTypeExpressions) {
JetType[] parameterTypeOptions = parameterTypeExpression.getOptions(); JetType[] parameterTypeOptions = parameterTypeExpression.getOptions();
String[] parameterTypeOptionStrings = parameterTypeExpression.getOptionStrings(); String[] parameterTypeOptionStrings = parameterTypeExpression.getOptionStrings();
@@ -757,7 +760,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase {
} }
builder.replaceElement(func, TextRange.create(3, 3), TYPE_PARAMETER_LIST_VARIABLE_NAME, null, false); // ((3, 3) is after "fun") builder.replaceElement(func, TextRange.create(3, 3), TYPE_PARAMETER_LIST_VARIABLE_NAME, null, false); // ((3, 3) is after "fun")
return new TypeParameterListExpression(ownerTypeParameterNames, typeParameterMap); return new TypeParameterListExpression(receiverTypeParametersNotInScope, typeParameterMap);
} }
private TypeExpression[] setupParameterTypeTemplates(@NotNull Project project, @NotNull TemplateBuilder builder, private TypeExpression[] setupParameterTypeTemplates(@NotNull Project project, @NotNull TemplateBuilder builder,
@@ -863,25 +866,28 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase {
} }
@NotNull @NotNull
private static String renderTypeShort(JetType type) { private static String renderTypeShort(@NotNull JetType type) {
return DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(type); return DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(type);
} }
@NotNull @NotNull
private static String renderTypeLong(JetType type) { private static String renderTypeLong(@NotNull JetType type) {
return DescriptorRenderer.TEXT.renderType(type); return DescriptorRenderer.TEXT.renderType(type);
} }
@NotNull @NotNull
private static String[] getTypeParameterNamesNotInScope(Collection<? extends TypeParameterDescriptor> typeParameters, JetScope scope) { private static TypeParameterDescriptor[] getTypeParameterNamesNotInScope(
List<String> typeParameterNames = new ArrayList<String>(); @NotNull Collection<? extends TypeParameterDescriptor> typeParameters,
@NotNull JetScope scope
) {
List<TypeParameterDescriptor> typeParameterNames = new ArrayList<TypeParameterDescriptor>();
for (TypeParameterDescriptor typeParameter : typeParameters) { for (TypeParameterDescriptor typeParameter : typeParameters) {
ClassifierDescriptor classifier = scope.getClassifier(typeParameter.getName()); ClassifierDescriptor classifier = scope.getClassifier(typeParameter.getName());
if (classifier == null || !classifier.equals(typeParameter)) { if (classifier == null || !classifier.equals(typeParameter)) {
typeParameterNames.add(typeParameter.getName().getIdentifier()); typeParameterNames.add(typeParameter);
} }
} }
return ArrayUtil.toStringArray(typeParameterNames); return typeParameterNames.toArray(new TypeParameterDescriptor[typeParameterNames.size()]);
} }
@NotNull @NotNull