From 740ef94bcf97b304230a8998d7f432c153585b69 Mon Sep 17 00:00:00 2001 From: Semyon Proshev Date: Fri, 7 Oct 2016 15:25:19 +0300 Subject: [PATCH] Use list of types for element types instead of array in PyTupleType --- .../com/jetbrains/python/psi/PyPsiFacade.java | 3 +- .../codeInsight/PyTypingTypeProvider.java | 14 +++---- .../stdlib/PyStdlibTypeProvider.java | 19 +++------- .../psi/impl/PyCallExpressionHelper.java | 3 +- .../psi/impl/PyKeyValueExpressionImpl.java | 6 ++- .../python/psi/impl/PyPsiFacadeImpl.java | 7 ++-- .../psi/impl/PyTupleExpressionImpl.java | 10 ++--- .../python/psi/types/PyTupleType.java | 37 +++++++++---------- .../python/psi/types/PyTypeChecker.java | 19 ++++------ .../python/psi/types/PyTypeParser.java | 8 ++-- 10 files changed, 55 insertions(+), 71 deletions(-) diff --git a/python/psi-api/src/com/jetbrains/python/psi/PyPsiFacade.java b/python/psi-api/src/com/jetbrains/python/psi/PyPsiFacade.java index 6f4cd617f78d..c27881c65887 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/PyPsiFacade.java +++ b/python/psi-api/src/com/jetbrains/python/psi/PyPsiFacade.java @@ -27,6 +27,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Collection; +import java.util.List; /** * @author yole @@ -53,7 +54,7 @@ public abstract class PyPsiFacade { public abstract PyType createUnionType(@NotNull Collection members); @Nullable - public abstract PyType createTupleType(@NotNull Collection members, @NotNull PsiElement anchor); + public abstract PyType createTupleType(@NotNull List members, @NotNull PsiElement anchor); @Nullable public abstract PyType parseTypeAnnotation(@NotNull String annotation, @NotNull PsiElement anchor); diff --git a/python/src/com/jetbrains/python/codeInsight/PyTypingTypeProvider.java b/python/src/com/jetbrains/python/codeInsight/PyTypingTypeProvider.java index cdd550e018fc..fd424378e7e6 100644 --- a/python/src/com/jetbrains/python/codeInsight/PyTypingTypeProvider.java +++ b/python/src/com/jetbrains/python/codeInsight/PyTypingTypeProvider.java @@ -24,6 +24,7 @@ import com.intellij.openapi.util.Ref; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiPolyVariantReference; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashSet; import com.jetbrains.python.PyNames; import com.jetbrains.python.psi.*; @@ -383,7 +384,7 @@ public class PyTypingTypeProvider extends PyTypeProviderBase { if (elementTypes.size() > 1 && elementTypes.get(1) instanceof PyTypeParser.EllipsisType) { return PyTupleType.createHomogeneous(resolved, elementTypes.get(0)); } - return PyTupleType.create(resolved, elementTypes.toArray(new PyType[elementTypes.size()])); + return PyTupleType.create(resolved, elementTypes); } final PyType builtinCollection = getBuiltinCollection(resolved); if (builtinCollection instanceof PyClassType) { @@ -467,11 +468,8 @@ public class PyTypingTypeProvider extends PyTypeProviderBase { final PyExpression expr = ((PyExpressionStatement)element).getExpression(); if (expr instanceof PyTupleExpression) { final PyTupleExpression tupleExpr = (PyTupleExpression)expr; - final List elementTypes = new ArrayList<>(); - for (PyExpression elementExpr : tupleExpr.getElements()) { - elementTypes.add(getType(elementExpr, context)); - } - return PyTupleType.create(anchor, elementTypes.toArray(new PyType[elementTypes.size()])); + final List elementTypes = ContainerUtil.map(tupleExpr.getElements(), elementExpr -> getType(elementExpr, context)); + return PyTupleType.create(anchor, elementTypes); } return getType(expr, context); } @@ -594,7 +592,7 @@ public class PyTypingTypeProvider extends PyTypeProviderBase { return PyTupleType.createHomogeneous(element, indexTypes.get(0)); } } - return PyTupleType.create(element, indexTypes.toArray(new PyType[indexTypes.size()])); + return PyTupleType.create(element, indexTypes); } else if (indexExpr != null) { return new PyCollectionTypeImpl(cls, false, indexTypes); @@ -644,7 +642,7 @@ public class PyTypingTypeProvider extends PyTypeProviderBase { } } } - return !elements.isEmpty() ? elements : Collections.singletonList(expression); + return !elements.isEmpty() ? elements : Collections.singletonList(expression); } @NotNull diff --git a/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibTypeProvider.java b/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibTypeProvider.java index 4103e8f7a654..5125a710f906 100644 --- a/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibTypeProvider.java +++ b/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibTypeProvider.java @@ -39,10 +39,7 @@ import com.jetbrains.python.psi.types.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; +import java.util.*; import static com.jetbrains.python.psi.PyUtil.as; @@ -254,7 +251,7 @@ public class PyStdlibTypeProvider extends PyTypeProviderBase { elementTypes[i * originalSize + j] = leftTupleType.getElementType(j); } } - return Ref.create(PyTupleType.create(multiplication, elementTypes)); + return Ref.create(PyTupleType.create(multiplication, Arrays.asList(elementTypes))); } } @@ -272,16 +269,10 @@ public class PyStdlibTypeProvider extends PyTypeProviderBase { // We may try to find the common type of elements of two homogeneous tuple as an alternative return null; } - - final PyType[] elementTypes = new PyType[leftTupleType.getElementCount() + rightTupleType.getElementCount()]; - for (int i = 0; i < leftTupleType.getElementCount(); i++) { - elementTypes[i] = leftTupleType.getElementType(i); - } - for (int i = 0; i < rightTupleType.getElementCount(); i++) { - elementTypes[i + leftTupleType.getElementCount()] = rightTupleType.getElementType(i); - } - return Ref.create(PyTupleType.create(addition, elementTypes)); + final List newElementTypes = ContainerUtil.concat(leftTupleType.getElementTypes(context), + rightTupleType.getElementTypes(context)); + return Ref.create(PyTupleType.create(addition, newElementTypes)); } } diff --git a/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java b/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java index a1048d61cf2e..676726ff42e6 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java +++ b/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java @@ -542,8 +542,7 @@ public class PyCallExpressionHelper { if (cls != null && cls != init.getContainingClass()) { if (t instanceof PyTupleType) { final PyTupleType tupleType = (PyTupleType)t; - final List elementTypes = tupleType.getElementTypes(context); - final PyTupleType newTupleType = new PyTupleType(cls, elementTypes.toArray(new PyType[0]), tupleType.isHomogeneous()); + final PyTupleType newTupleType = new PyTupleType(cls, tupleType.getElementTypes(context), tupleType.isHomogeneous()); return Ref.create(newTupleType); } diff --git a/python/src/com/jetbrains/python/psi/impl/PyKeyValueExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyKeyValueExpressionImpl.java index 15667ab5e496..5970464563b3 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyKeyValueExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyKeyValueExpressionImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * 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. @@ -25,6 +25,8 @@ import com.jetbrains.python.psi.types.TypeEvalContext; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Arrays; + /** * @author yole */ @@ -40,7 +42,7 @@ public class PyKeyValueExpressionImpl extends PyElementImpl implements PyKeyValu if (value != null) { valueType = context.getType(value); } - return PyTupleType.create(this, new PyType[] {keyType, valueType}); + return PyTupleType.create(this, Arrays.asList(keyType, valueType)); } @NotNull diff --git a/python/src/com/jetbrains/python/psi/impl/PyPsiFacadeImpl.java b/python/src/com/jetbrains/python/psi/impl/PyPsiFacadeImpl.java index 1e69212ae101..8c82802fee87 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyPsiFacadeImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyPsiFacadeImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * 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. @@ -31,6 +31,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Collection; +import java.util.List; /** * @author yole @@ -72,8 +73,8 @@ public class PyPsiFacadeImpl extends PyPsiFacade { @Nullable @Override - public PyType createTupleType(@NotNull Collection members, @NotNull PsiElement anchor) { - return PyTupleType.create(anchor, members.toArray(new PyType[members.size()])); + public PyType createTupleType(@NotNull List members, @NotNull PsiElement anchor) { + return PyTupleType.create(anchor, members); } @Nullable diff --git a/python/src/com/jetbrains/python/psi/impl/PyTupleExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyTupleExpressionImpl.java index 392b9f1068f2..81ec65fb8509 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyTupleExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyTupleExpressionImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * 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. @@ -16,6 +16,7 @@ package com.jetbrains.python.psi.impl; import com.intellij.lang.ASTNode; +import com.intellij.util.containers.ContainerUtil; import com.jetbrains.python.psi.*; import com.jetbrains.python.psi.types.PyTupleType; import com.jetbrains.python.psi.types.PyType; @@ -39,12 +40,7 @@ public class PyTupleExpressionImpl extends PySequenceExpressionImpl implements P } public PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) { - final PyExpression[] elements = getElements(); - final PyType[] types = new PyType[elements.length]; - for (int i = 0; i < types.length; i++) { - types [i] = context.getType(elements [i]); - } - return PyTupleType.create(this, types); + return PyTupleType.create(this, ContainerUtil.map(getElements(), context::getType)); } public Iterator iterator() { diff --git a/python/src/com/jetbrains/python/psi/types/PyTupleType.java b/python/src/com/jetbrains/python/psi/types/PyTupleType.java index 9db892be73c5..5a98be568e63 100644 --- a/python/src/com/jetbrains/python/psi/types/PyTupleType.java +++ b/python/src/com/jetbrains/python/psi/types/PyTupleType.java @@ -23,19 +23,21 @@ import com.jetbrains.python.psi.impl.PyBuiltinCache; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Arrays; +import java.util.Collections; import java.util.List; /** * @author yole */ public class PyTupleType extends PyClassTypeImpl implements PyCollectionType { - private final PyType[] myElementTypes; + + @NotNull + private final List myElementTypes; private final boolean myHomogeneous; @Nullable - public static PyTupleType create(@NotNull PsiElement anchor, @NotNull PyType[] elementTypes) { - PyClass tuple = PyBuiltinCache.getInstance(anchor).getClass(PyNames.TUPLE); + public static PyTupleType create(@NotNull PsiElement anchor, @NotNull List elementTypes) { + final PyClass tuple = PyBuiltinCache.getInstance(anchor).getClass(PyNames.TUPLE); if (tuple != null) { return new PyTupleType(tuple, elementTypes, false); } @@ -44,26 +46,23 @@ public class PyTupleType extends PyClassTypeImpl implements PyCollectionType { @Nullable public static PyTupleType createHomogeneous(@NotNull PsiElement anchor, @Nullable PyType elementType) { - PyClass tuple = PyBuiltinCache.getInstance(anchor).getClass(PyNames.TUPLE); + final PyClass tuple = PyBuiltinCache.getInstance(anchor).getClass(PyNames.TUPLE); if (tuple != null) { - return new PyTupleType(tuple, new PyType[]{elementType}, true); + return new PyTupleType(tuple, Collections.singletonList(elementType), true); } return null; } - public PyTupleType(@NotNull PyClass tupleClass, @NotNull PyType[] elementTypes, boolean homogeneous) { + public PyTupleType(@NotNull PyClass tupleClass, @NotNull List elementTypes, boolean homogeneous) { super(tupleClass, false); myElementTypes = elementTypes; myHomogeneous = homogeneous; } - public PyTupleType(@NotNull PyTupleType origin, @NotNull PyType[] elementTypes) { - this(origin.getPyClass(), elementTypes, false); - } - + @NotNull public String getName() { if (myHomogeneous) { - return "(" + (getTypeName(myElementTypes[0])) + ", ...)"; + return "(" + (getTypeName(myElementTypes.get(0))) + ", ...)"; } return "(" + StringUtil.join(myElementTypes, PyTupleType::getTypeName, ", ") + ")"; } @@ -87,16 +86,16 @@ public class PyTupleType extends PyClassTypeImpl implements PyCollectionType { @Nullable public PyType getElementType(int index) { if (myHomogeneous) { - return myElementTypes[0]; + return myElementTypes.get(0); } - if (index >= 0 && index < myElementTypes.length) { - return myElementTypes[index]; + if (index >= 0 && index < myElementTypes.size()) { + return myElementTypes.get(index); } return null; } public int getElementCount() { - return myHomogeneous ? -1 : myElementTypes.length; + return myHomogeneous ? -1 : myElementTypes.size(); } public boolean isHomogeneous() { @@ -111,7 +110,7 @@ public class PyTupleType extends PyClassTypeImpl implements PyCollectionType { PyTupleType that = (PyTupleType)o; - if (!Arrays.equals(myElementTypes, that.myElementTypes)) return false; + if (!myElementTypes.equals(that.myElementTypes)) return false; return true; } @@ -119,13 +118,13 @@ public class PyTupleType extends PyClassTypeImpl implements PyCollectionType { @Override public int hashCode() { int result = super.hashCode(); - result = 31 * result + (myElementTypes != null ? Arrays.hashCode(myElementTypes) : 0); + result = 31 * result + myElementTypes.hashCode(); return result; } @NotNull @Override public List getElementTypes(@NotNull TypeEvalContext context) { - return Arrays.asList(myElementTypes); + return myElementTypes; } } diff --git a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java index c285a94db599..3d30c0c1ef6e 100644 --- a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java +++ b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java @@ -367,20 +367,17 @@ public class PyTypeChecker { return new PyCollectionTypeImpl(collection.getPyClass(), collection.isDefinition(), substitutes); } else if (type instanceof PyTupleType) { - final PyTupleType tuple = (PyTupleType)type; + final PyTupleType tupleType = (PyTupleType)type; + final PyClass tupleClass = tupleType.getPyClass(); - if (tuple.isHomogeneous()) { - return PyTupleType.createHomogeneous(tuple.getPyClass(), substitute(tuple.getElementType(0), substitutions, context)); - } else { - final int elementCount = tuple.getElementCount(); - final PyType[] elementTypes = new PyType[elementCount]; + final List oldElementTypes = tupleType.isHomogeneous() + ? Collections.singletonList(tupleType.getElementType(0)) + : tupleType.getElementTypes(context); - for (int i = 0; i < elementCount; i++) { - elementTypes[i] = substitute(tuple.getElementType(i), substitutions, context); - } + final List newElementTypes = + ContainerUtil.map(oldElementTypes, elementType -> substitute(elementType, substitutions, context)); - return PyTupleType.create(tuple.getPyClass(), elementTypes); - } + return new PyTupleType(tupleClass, newElementTypes, tupleType.isHomogeneous()); } else if (type instanceof PyCallableType) { final PyCallableType callable = (PyCallableType)type; diff --git a/python/src/com/jetbrains/python/psi/types/PyTypeParser.java b/python/src/com/jetbrains/python/psi/types/PyTypeParser.java index 1ab0980a5e0d..5d282e0cc4a3 100644 --- a/python/src/com/jetbrains/python/psi/types/PyTypeParser.java +++ b/python/src/com/jetbrains/python/psi/types/PyTypeParser.java @@ -57,8 +57,8 @@ import static com.jetbrains.python.psi.types.functionalParser.FunctionalParserBa * @author vlan */ public class PyTypeParser { - private static final ParseResult EMPTY_RESULT = new ParseResult(null, null, Collections.emptyMap(), Collections.emptyMap(), - Collections.emptyMap()); + private static final ParseResult EMPTY_RESULT = new ParseResult(null, null, Collections.emptyMap(), Collections.emptyMap(), + Collections.emptyMap()); public static class ParseResult { @Nullable private final PsiElement myElement; @@ -78,7 +78,7 @@ public class PyTypeParser { } ParseResult(@Nullable PsiElement element, @NotNull PyType type, @NotNull TextRange range) { - this(element, type, ImmutableMap.of(range, type), ImmutableMap.of(type, range), ImmutableMap.of()); + this(element, type, ImmutableMap.of(range, type), ImmutableMap.of(type, range), ImmutableMap.of()); } @Nullable @@ -165,7 +165,7 @@ public class PyTypeParser { result = result.merge(r); types.add(r.getType()); } - return result.withType(PyTupleType.create(anchor, types.toArray(new PyType[types.size()]))); + return result.withType(PyTupleType.create(anchor, types)); }) .named("tuple-type");