From bbcee93c26ff557cc29212fa3e0890f02fa97c6a Mon Sep 17 00:00:00 2001 From: Andrey Vlasovskikh Date: Fri, 2 Aug 2013 15:41:20 +0400 Subject: [PATCH] Use object instead of pair for describing function type parameters --- .../python/psi/impl/PyJavaClassType.java | 4 +- .../python/psi/impl/PyJavaMethodType.java | 4 +- .../python/psi/types/PyCallableParameter.java | 19 +++++++ .../python/psi/types/PyCallableType.java | 5 +- .../documentation/PyTypeModelBuilder.java | 7 ++- .../psi/types/PyCallableParameterImpl.java | 49 +++++++++++++++++++ .../python/psi/types/PyCallableTypeImpl.java | 16 +++--- .../python/psi/types/PyClassTypeImpl.java | 2 +- .../python/psi/types/PyFunctionType.java | 11 ++--- .../python/psi/types/PyTypeChecker.java | 31 ++++++------ .../python/psi/types/PyTypeParser.java | 6 +-- .../jetbrains/python/PyTypeParserTest.java | 13 +++-- 12 files changed, 118 insertions(+), 49 deletions(-) create mode 100644 python/psi-api/src/com/jetbrains/python/psi/types/PyCallableParameter.java create mode 100644 python/src/com/jetbrains/python/psi/types/PyCallableParameterImpl.java diff --git a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java index adbe3806074f..5a74a6e0f1a3 100644 --- a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java +++ b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java @@ -1,6 +1,5 @@ package com.jetbrains.python.psi.impl; -import com.intellij.openapi.util.Pair; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiField; import com.intellij.psi.PsiMethod; @@ -12,6 +11,7 @@ import com.jetbrains.python.psi.PyQualifiedExpression; import com.jetbrains.python.psi.resolve.CompletionVariantsProcessor; import com.jetbrains.python.psi.resolve.PyResolveContext; import com.jetbrains.python.psi.resolve.RatedResolveResult; +import com.jetbrains.python.psi.types.PyCallableParameter; import com.jetbrains.python.psi.types.PyClassLikeType; import com.jetbrains.python.psi.types.PyType; import com.jetbrains.python.psi.types.TypeEvalContext; @@ -101,7 +101,7 @@ public class PyJavaClassType implements PyClassLikeType { @Nullable @Override - public List> getParameters(@NotNull TypeEvalContext context) { + public List getParameters(@NotNull TypeEvalContext context) { return null; } diff --git a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaMethodType.java b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaMethodType.java index 3ef7355229b9..180ad2377503 100644 --- a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaMethodType.java +++ b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaMethodType.java @@ -1,6 +1,5 @@ package com.jetbrains.python.psi.impl; -import com.intellij.openapi.util.Pair; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiMethod; import com.intellij.util.ArrayUtil; @@ -10,6 +9,7 @@ import com.jetbrains.python.psi.PyExpression; import com.jetbrains.python.psi.PyQualifiedExpression; import com.jetbrains.python.psi.resolve.PyResolveContext; import com.jetbrains.python.psi.resolve.RatedResolveResult; +import com.jetbrains.python.psi.types.PyCallableParameter; import com.jetbrains.python.psi.types.PyCallableType; import com.jetbrains.python.psi.types.PyType; import com.jetbrains.python.psi.types.TypeEvalContext; @@ -42,7 +42,7 @@ public class PyJavaMethodType implements PyCallableType { @Nullable @Override - public List> getParameters(@NotNull TypeEvalContext context) { + public List getParameters(@NotNull TypeEvalContext context) { return null; } diff --git a/python/psi-api/src/com/jetbrains/python/psi/types/PyCallableParameter.java b/python/psi-api/src/com/jetbrains/python/psi/types/PyCallableParameter.java new file mode 100644 index 000000000000..9347e22b3d2d --- /dev/null +++ b/python/psi-api/src/com/jetbrains/python/psi/types/PyCallableParameter.java @@ -0,0 +1,19 @@ +package com.jetbrains.python.psi.types; + +import com.jetbrains.python.psi.PyParameter; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author vlan + */ +public interface PyCallableParameter { + @Nullable + String getName(); + + @Nullable + PyType getType(); + + @Nullable + PyParameter getParameter(); +} diff --git a/python/psi-api/src/com/jetbrains/python/psi/types/PyCallableType.java b/python/psi-api/src/com/jetbrains/python/psi/types/PyCallableType.java index 482df90af817..261a7eb443d2 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/types/PyCallableType.java +++ b/python/psi-api/src/com/jetbrains/python/psi/types/PyCallableType.java @@ -1,6 +1,5 @@ package com.jetbrains.python.psi.types; -import com.intellij.openapi.util.Pair; import com.jetbrains.python.psi.PyQualifiedExpression; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -32,8 +31,8 @@ public interface PyCallableType extends PyType { /** * Returns the list of parameter types. * - * @return list of (name, type) pairs or null if not applicable. Name and type in pair may be null. + * @return list of parameter info null if not applicable. */ @Nullable - List> getParameters(@NotNull TypeEvalContext context); + List getParameters(@NotNull TypeEvalContext context); } diff --git a/python/src/com/jetbrains/python/documentation/PyTypeModelBuilder.java b/python/src/com/jetbrains/python/documentation/PyTypeModelBuilder.java index 8e6db24d6d8b..8a37daa6b275 100644 --- a/python/src/com/jetbrains/python/documentation/PyTypeModelBuilder.java +++ b/python/src/com/jetbrains/python/documentation/PyTypeModelBuilder.java @@ -4,7 +4,6 @@ import com.google.common.base.Function; import com.google.common.collect.Collections2; import com.google.common.collect.Lists; import com.google.common.collect.Maps; -import com.intellij.openapi.util.Pair; import com.intellij.psi.PsiElement; import com.jetbrains.python.PyNames; import com.jetbrains.python.psi.Callable; @@ -206,11 +205,11 @@ public class PyTypeModelBuilder { private TypeModel build(@NotNull PyCallableType type) { List parameterModels = null; - final List> parameters = type.getParameters(myContext); + final List parameters = type.getParameters(myContext); if (parameters != null) { parameterModels = new ArrayList(); - for (Pair parameter : parameters) { - parameterModels.add(new ParamType(parameter.getFirst(), build(parameter.getSecond(), true))); + for (PyCallableParameter parameter : parameters) { + parameterModels.add(new ParamType(parameter.getName(), build(parameter.getType(), true))); } } final PyType ret = type.getCallType(myContext, null); diff --git a/python/src/com/jetbrains/python/psi/types/PyCallableParameterImpl.java b/python/src/com/jetbrains/python/psi/types/PyCallableParameterImpl.java new file mode 100644 index 000000000000..2d99cdbf20d6 --- /dev/null +++ b/python/src/com/jetbrains/python/psi/types/PyCallableParameterImpl.java @@ -0,0 +1,49 @@ +package com.jetbrains.python.psi.types; + +import com.jetbrains.python.psi.PyParameter; +import org.jetbrains.annotations.Nullable; + +/** + * @author vlan + */ +public class PyCallableParameterImpl implements PyCallableParameter { + @Nullable private final String myName; + @Nullable private final PyType myType; + @Nullable private final PyParameter myElement; + + public PyCallableParameterImpl(@Nullable String name, @Nullable PyType type) { + myName = name; + myType = type; + myElement = null; + } + + public PyCallableParameterImpl(@Nullable PyParameter element, @Nullable PyType type) { + myName = null; + myType = type; + myElement = element; + } + + @Nullable + @Override + public String getName() { + if (myName != null) { + return myName; + } + else if (myElement != null) { + return myElement.getName(); + } + return null; + } + + @Nullable + @Override + public PyType getType() { + return myType; + } + + @Nullable + @Override + public PyParameter getParameter() { + return myElement; + } +} diff --git a/python/src/com/jetbrains/python/psi/types/PyCallableTypeImpl.java b/python/src/com/jetbrains/python/psi/types/PyCallableTypeImpl.java index 8b3cb754b437..9e655f9036e9 100644 --- a/python/src/com/jetbrains/python/psi/types/PyCallableTypeImpl.java +++ b/python/src/com/jetbrains/python/psi/types/PyCallableTypeImpl.java @@ -1,6 +1,5 @@ package com.jetbrains.python.psi.types; -import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.Function; import com.intellij.util.ProcessingContext; @@ -19,10 +18,10 @@ import java.util.List; * @author vlan */ public class PyCallableTypeImpl implements PyCallableType { - @Nullable private final List> myParameters; + @Nullable private final List myParameters; @Nullable private final PyType myReturnType; - public PyCallableTypeImpl(@Nullable List> parameters, @Nullable PyType returnType) { + public PyCallableTypeImpl(@Nullable List parameters, @Nullable PyType returnType) { myParameters = parameters; myReturnType = returnType; } @@ -40,7 +39,7 @@ public class PyCallableTypeImpl implements PyCallableType { @Nullable @Override - public List> getParameters(@NotNull TypeEvalContext context) { + public List getParameters(@NotNull TypeEvalContext context) { return myParameters; } @@ -61,16 +60,17 @@ public class PyCallableTypeImpl implements PyCallableType { @Nullable @Override public String getName() { + final TypeEvalContext context = TypeEvalContext.codeInsightFallback(); return String.format("(%s) -> %s", myParameters != null ? StringUtil.join(myParameters, - new Function, String>() { + new Function() { @Override - public String fun(Pair param) { + public String fun(PyCallableParameter param) { if (param != null) { final StringBuilder builder = new StringBuilder(); - final String name = param.getFirst(); - final PyType type = param.getSecond(); + final String name = param.getName(); + final PyType type = param.getType(); if (name != null) { builder.append(name); if (type != null) { diff --git a/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java b/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java index 446aba417165..de9cc6b39c68 100644 --- a/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java +++ b/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java @@ -279,7 +279,7 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType { @Nullable @Override - public List> getParameters(@NotNull TypeEvalContext context) { + public List getParameters(@NotNull TypeEvalContext context) { return null; } diff --git a/python/src/com/jetbrains/python/psi/types/PyFunctionType.java b/python/src/com/jetbrains/python/psi/types/PyFunctionType.java index 20072ba86284..fd3e3a8f4d27 100644 --- a/python/src/com/jetbrains/python/psi/types/PyFunctionType.java +++ b/python/src/com/jetbrains/python/psi/types/PyFunctionType.java @@ -1,6 +1,5 @@ package com.jetbrains.python.psi.types; -import com.intellij.openapi.util.Pair; import com.intellij.util.ProcessingContext; import com.jetbrains.python.psi.*; import com.jetbrains.python.psi.resolve.PyResolveContext; @@ -37,13 +36,11 @@ public class PyFunctionType implements PyCallableType { @Nullable @Override - public List> getParameters(@NotNull TypeEvalContext context) { - final List> result = new ArrayList>(); + public List getParameters(@NotNull TypeEvalContext context) { + final List result = new ArrayList(); for (PyParameter parameter : myCallable.getParameterList().getParameters()) { - if (parameter instanceof PyNamedParameter) { - final PyNamedParameter namedParameter = (PyNamedParameter)parameter; - result.add(Pair.create(getParameterName(namedParameter), context.getType(namedParameter))); - } + final PyType type = parameter instanceof PyTypedElement ? context.getType((PyTypedElement)parameter) : null; + result.add(new PyCallableParameterImpl(parameter, type)); } return result; } diff --git a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java index 4c3660dcbdb3..92ae7ab35caf 100644 --- a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java +++ b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java @@ -1,6 +1,5 @@ package com.jetbrains.python.psi.types; -import com.intellij.openapi.util.Pair; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiPolyVariantReference; import com.intellij.psi.PsiReference; @@ -145,15 +144,15 @@ public class PyTypeChecker { final PyCallableType expectedCallable = (PyCallableType)expected; final PyCallableType actualCallable = (PyCallableType)actual; if (expectedCallable.isCallable() && actualCallable.isCallable()) { - final List> expectedParameters = expectedCallable.getParameters(context); - final List> actualParameters = actualCallable.getParameters(context); + final List expectedParameters = expectedCallable.getParameters(context); + final List actualParameters = actualCallable.getParameters(context); if (expectedParameters != null && actualParameters != null) { final int size = Math.min(expectedParameters.size(), actualParameters.size()); for (int i = 0; i < size; i++) { - final Pair expectedParam = expectedParameters.get(i); - final Pair actualParam = actualParameters.get(i); + final PyCallableParameter expectedParam = expectedParameters.get(i); + final PyCallableParameter actualParam = actualParameters.get(i); // TODO: Check named and star params, not only positional ones - if (!match(expectedParam.getSecond(), actualParam.getSecond(), context, substitutions, recursive)) { + if (!match(expectedParam.getType(), actualParam.getType(), context, substitutions, recursive)) { return false; } } @@ -234,11 +233,11 @@ public class PyTypeChecker { } else if (type instanceof PyCallableType) { final PyCallableType callable = (PyCallableType)type; - final List> parameters = callable.getParameters(context); + final List parameters = callable.getParameters(context); if (parameters != null) { - for (Pair parameter : parameters) { + for (PyCallableParameter parameter : parameters) { if (parameter != null) { - collectGenerics(parameter.getSecond(), context, collected, visited); + collectGenerics(parameter.getType(), context, collected, visited); } } } @@ -280,12 +279,16 @@ public class PyTypeChecker { } else if (type instanceof PyCallableType) { final PyCallableType callable = (PyCallableType)type; - List> substParams = null; - final List> parameters = callable.getParameters(context); + List substParams = null; + final List parameters = callable.getParameters(context); if (parameters != null) { - substParams = new ArrayList>(); - for (Pair parameter : parameters) { - substParams.add(Pair.create(parameter.getFirst(), substitute(parameter.getSecond(), substitutions, context))); + substParams = new ArrayList(); + for (PyCallableParameter parameter : parameters) { + final PyType substType = substitute(parameter.getType(), substitutions, context); + final PyCallableParameter subst = parameter.getParameter() != null ? + new PyCallableParameterImpl(parameter.getParameter(), substType) : + new PyCallableParameterImpl(parameter.getName(), substType); + substParams.add(subst); } } final PyType substResult = substitute(callable.getCallType(context, null), substitutions, context); diff --git a/python/src/com/jetbrains/python/psi/types/PyTypeParser.java b/python/src/com/jetbrains/python/psi/types/PyTypeParser.java index 7aab2400b333..7150ab1413ae 100644 --- a/python/src/com/jetbrains/python/psi/types/PyTypeParser.java +++ b/python/src/com/jetbrains/python/psi/types/PyTypeParser.java @@ -230,7 +230,7 @@ public class PyTypeParser { new Function>, ParseResult>, ParseResult>() { @Override public ParseResult fun(Pair>, ParseResult> value) { - final List> parameters = new ArrayList>(); + final List parameters = new ArrayList(); final ParseResult returnResult = value.getSecond(); ParseResult result; final Pair> firstPair = value.getFirst(); @@ -238,10 +238,10 @@ public class PyTypeParser { final ParseResult first = firstPair.getFirst(); final List second = firstPair.getSecond(); result = first; - parameters.add(Pair.create(null, first.getType())); + parameters.add(new PyCallableParameterImpl((String)null, first.getType())); for (ParseResult r : second) { result = result.merge(r); - parameters.add(Pair.create(null, r.getType())); + parameters.add(new PyCallableParameterImpl((String)null, r.getType())); } result = result.merge(returnResult); } diff --git a/python/testSrc/com/jetbrains/python/PyTypeParserTest.java b/python/testSrc/com/jetbrains/python/PyTypeParserTest.java index 105893830283..9407a30d2363 100644 --- a/python/testSrc/com/jetbrains/python/PyTypeParserTest.java +++ b/python/testSrc/com/jetbrains/python/PyTypeParserTest.java @@ -1,6 +1,5 @@ package com.jetbrains.python; -import com.intellij.openapi.util.Pair; import com.jetbrains.python.fixtures.PyTestCase; import com.jetbrains.python.psi.types.*; @@ -237,11 +236,15 @@ public class PyTypeParserTest extends PyTestCase { assertNotNull(callableType); final PyType returnType = callableType.getCallType(getTypeEvalContext(), null); assertInstanceOf(returnType, PyGenericType.class); - final List> parameterTypes = callableType.getParameters(getTypeEvalContext()); + final List parameterTypes = callableType.getParameters(getTypeEvalContext()); assertNotNull(parameterTypes); assertEquals(2, parameterTypes.size()); - assertEquals("int", parameterTypes.get(0).getSecond().getName()); - assertEquals("T", parameterTypes.get(1).getSecond().getName()); + final PyType type0 = parameterTypes.get(0).getType(); + assertNotNull(type0); + assertEquals("int", type0.getName()); + final PyType type1 = parameterTypes.get(1).getType(); + assertNotNull(type1); + assertEquals("T", type1.getName()); } public void testCallableWithoutArgs() { @@ -253,7 +256,7 @@ public class PyTypeParserTest extends PyTestCase { final PyType returnType = callableType.getCallType(getTypeEvalContext(), null); assertNotNull(returnType); assertEquals("int", returnType.getName()); - final List> parameterTypes = callableType.getParameters(getTypeEvalContext()); + final List parameterTypes = callableType.getParameters(getTypeEvalContext()); assertNotNull(parameterTypes); assertEquals(0, parameterTypes.size()); }