diff --git a/python/psi-api/src/com/jetbrains/python/psi/PyCustomizableStubElementType.java b/python/psi-api/src/com/jetbrains/python/psi/PyCustomizableStubElementType.java new file mode 100644 index 000000000000..a1dccab8b600 --- /dev/null +++ b/python/psi-api/src/com/jetbrains/python/psi/PyCustomizableStubElementType.java @@ -0,0 +1,53 @@ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.jetbrains.python.psi; + +import com.intellij.psi.stubs.StubInputStream; +import com.intellij.psi.stubs.StubOutputStream; +import com.jetbrains.python.psi.impl.stubs.PyCustomStub; +import com.jetbrains.python.psi.impl.stubs.PyCustomStubType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.util.List; + +public interface PyCustomizableStubElementType> { + + @NotNull + List getExtensions(); + + @Nullable + default Stub createCustomStub(@NotNull Psi psi) { + for (StubType type : getExtensions()) { + final Stub stub = type.createStub(psi); + if (stub != null) return stub; + } + + return null; + } + + default void serializeCustomStub(@Nullable Stub stub, @NotNull StubOutputStream stream) throws IOException { + final boolean hasCustomStub = stub != null; + stream.writeBoolean(hasCustomStub); + + if (hasCustomStub) { + stream.writeName(stub.getTypeClass().getCanonicalName()); + stub.serialize(stream); + } + } + + @Nullable + default Stub deserializeCustomStub(@NotNull StubInputStream stream) throws IOException { + if (stream.readBoolean()) { + final String typeName = stream.readNameString(); + for (StubType type : getExtensions()) { + if (type.getClass().getCanonicalName().equals(typeName)) { + return type.deserializeStub(stream); + } + } + throw new IOException("Unknown custom stub type " + typeName); + } + + return null; + } +} diff --git a/python/psi-api/src/com/jetbrains/python/psi/impl/stubs/CustomTargetExpressionStub.java b/python/psi-api/src/com/jetbrains/python/psi/impl/stubs/CustomTargetExpressionStub.java index 5f6485b881d7..1eb66de0a8cf 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/impl/stubs/CustomTargetExpressionStub.java +++ b/python/psi-api/src/com/jetbrains/python/psi/impl/stubs/CustomTargetExpressionStub.java @@ -15,20 +15,13 @@ */ package com.jetbrains.python.psi.impl.stubs; -import com.intellij.psi.stubs.StubOutputStream; import com.intellij.psi.util.QualifiedName; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.io.IOException; - /** * @author yole */ -public interface CustomTargetExpressionStub { - @NotNull - Class getTypeClass(); - void serialize(StubOutputStream stream) throws IOException; +public interface CustomTargetExpressionStub extends PyCustomStub { @Nullable QualifiedName getCalleeName(); diff --git a/python/psi-api/src/com/jetbrains/python/psi/impl/stubs/CustomTargetExpressionStubType.java b/python/psi-api/src/com/jetbrains/python/psi/impl/stubs/CustomTargetExpressionStubType.java index 8215dc15f5a1..818b5cd30459 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/impl/stubs/CustomTargetExpressionStubType.java +++ b/python/psi-api/src/com/jetbrains/python/psi/impl/stubs/CustomTargetExpressionStubType.java @@ -17,24 +17,17 @@ package com.jetbrains.python.psi.impl.stubs; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.psi.stubs.IndexSink; -import com.intellij.psi.stubs.StubInputStream; import com.jetbrains.python.psi.PyTargetExpression; import com.jetbrains.python.psi.stubs.PyTargetExpressionStub; -import org.jetbrains.annotations.Nullable; - -import java.io.IOException; /** * @author yole */ -public abstract class CustomTargetExpressionStubType { - public static final ExtensionPointName EP_NAME = ExtensionPointName.create("Pythonid.customTargetExpressionStubType"); +public abstract class CustomTargetExpressionStubType + implements PyCustomStubType { - @Nullable - public abstract T createStub(PyTargetExpression psi); - - @Nullable - public abstract T deserializeStub(StubInputStream stream) throws IOException; + public static final ExtensionPointName> EP_NAME = + ExtensionPointName.create("Pythonid.customTargetExpressionStubType"); public void indexStub(PyTargetExpressionStub stub, IndexSink sink) { } diff --git a/python/psi-api/src/com/jetbrains/python/psi/impl/stubs/PyCustomClassStub.java b/python/psi-api/src/com/jetbrains/python/psi/impl/stubs/PyCustomClassStub.java index ef1cb6c57e42..0312fd61107d 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/impl/stubs/PyCustomClassStub.java +++ b/python/psi-api/src/com/jetbrains/python/psi/impl/stubs/PyCustomClassStub.java @@ -1,24 +1,5 @@ // Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.jetbrains.python.psi.impl.stubs; -import com.intellij.psi.stubs.StubInputStream; -import com.intellij.psi.stubs.StubOutputStream; -import org.jetbrains.annotations.NotNull; - -import java.io.IOException; - -public interface PyCustomClassStub { - - /** - * @return type class to distinguish one custom stub from another. - */ - @NotNull - Class getTypeClass(); - - /** - * @param stream stream to serialize {@code this} stub - * @throws IOException - * @see PyCustomClassStubType#deserializeStub(StubInputStream) - */ - void serialize(@NotNull StubOutputStream stream) throws IOException; +public interface PyCustomClassStub extends PyCustomStub { } diff --git a/python/psi-api/src/com/jetbrains/python/psi/impl/stubs/PyCustomClassStubType.java b/python/psi-api/src/com/jetbrains/python/psi/impl/stubs/PyCustomClassStubType.java index 7651e3dc9225..2dcfee0d5dcb 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/impl/stubs/PyCustomClassStubType.java +++ b/python/psi-api/src/com/jetbrains/python/psi/impl/stubs/PyCustomClassStubType.java @@ -2,31 +2,10 @@ package com.jetbrains.python.psi.impl.stubs; import com.intellij.openapi.extensions.ExtensionPointName; -import com.intellij.psi.stubs.StubInputStream; -import com.intellij.psi.stubs.StubOutputStream; import com.jetbrains.python.psi.PyClass; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import java.io.IOException; +public abstract class PyCustomClassStubType implements PyCustomStubType { -public abstract class PyCustomClassStubType { - - public static final ExtensionPointName EP_NAME = ExtensionPointName.create("Pythonid.customClassStubType"); - - /** - * @param psi class to create stub for - * @return custom stub for given class or null. - */ - @Nullable - public abstract T createStub(@NotNull PyClass psi); - - /** - * @param stream stream containing serialized stub - * @return a custom stub instance or null if it could not be read. - * @throws IOException - * @see PyCustomClassStub#serialize(StubOutputStream) - */ - @Nullable - public abstract T deserializeStub(@NotNull StubInputStream stream) throws IOException; + public static final ExtensionPointName> EP_NAME = + ExtensionPointName.create("Pythonid.customClassStubType"); } diff --git a/python/psi-api/src/com/jetbrains/python/psi/impl/stubs/PyCustomStub.java b/python/psi-api/src/com/jetbrains/python/psi/impl/stubs/PyCustomStub.java new file mode 100644 index 000000000000..f6bf9e83b6e6 --- /dev/null +++ b/python/psi-api/src/com/jetbrains/python/psi/impl/stubs/PyCustomStub.java @@ -0,0 +1,24 @@ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.jetbrains.python.psi.impl.stubs; + +import com.intellij.psi.stubs.StubInputStream; +import com.intellij.psi.stubs.StubOutputStream; +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +public interface PyCustomStub { + + /** + * @return type class to distinguish one custom stub from another. + */ + @NotNull + Class getTypeClass(); + + /** + * @param stream stream to serialize {@code this} stub + * @throws IOException + * @see PyCustomStubType#deserializeStub(StubInputStream) + */ + void serialize(@NotNull StubOutputStream stream) throws IOException; +} diff --git a/python/psi-api/src/com/jetbrains/python/psi/impl/stubs/PyCustomStubType.java b/python/psi-api/src/com/jetbrains/python/psi/impl/stubs/PyCustomStubType.java new file mode 100644 index 000000000000..295851e95d1e --- /dev/null +++ b/python/psi-api/src/com/jetbrains/python/psi/impl/stubs/PyCustomStubType.java @@ -0,0 +1,29 @@ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.jetbrains.python.psi.impl.stubs; + +import com.intellij.psi.stubs.StubInputStream; +import com.intellij.psi.stubs.StubOutputStream; +import com.jetbrains.python.psi.PyElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; + +public interface PyCustomStubType { + + /** + * @param psi element to create stub for + * @return custom stub for the given psi or null. + */ + @Nullable + Stub createStub(@NotNull Psi psi); + + /** + * @param stream stream containing serialized stub + * @return a custom stub instance or null if it could not be read. + * @throws IOException + * @see PyCustomStub#serialize(StubOutputStream) + */ + @Nullable + Stub deserializeStub(@NotNull StubInputStream stream) throws IOException; +} diff --git a/python/src/com/jetbrains/python/psi/impl/stubs/PyClassElementType.java b/python/src/com/jetbrains/python/psi/impl/stubs/PyClassElementType.java index fcb14acf4a97..eba3a78da104 100644 --- a/python/src/com/jetbrains/python/psi/impl/stubs/PyClassElementType.java +++ b/python/src/com/jetbrains/python/psi/impl/stubs/PyClassElementType.java @@ -12,7 +12,6 @@ import com.jetbrains.python.psi.impl.PyClassImpl; import com.jetbrains.python.psi.impl.PyPsiUtils; import com.jetbrains.python.psi.resolve.PyResolveUtil; import com.jetbrains.python.psi.stubs.*; -import one.util.streamex.StreamEx; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -25,10 +24,8 @@ import static com.jetbrains.python.psi.PyUtil.as; /** * @author max */ -public class PyClassElementType extends PyStubElementType { - - @Nullable - private List myCustomStubTypes; +public class PyClassElementType extends PyStubElementType + implements PyCustomizableStubElementType> { public PyClassElementType() { this("CLASS_DECLARATION"); @@ -52,12 +49,6 @@ public class PyClassElementType extends PyStubElementType @Override @NotNull public PyClassStub createStub(@NotNull final PyClass psi, final StubElement parentStub) { - final PyCustomClassStub customStub = StreamEx - .of(getCustomStubTypes()) - .map(type -> type.createStub(psi)) - .findFirst(Objects::nonNull) - .orElse(null); - return new PyClassStubImpl(psi.getName(), parentStub, getSuperClassQNames(psi), @@ -67,7 +58,7 @@ public class PyClassElementType extends PyStubElementType psi.getOwnSlots(), PyPsiUtils.strValue(psi.getDocStringExpression()), getStubElementType(), - customStub); + createCustomStub(psi)); } @NotNull @@ -160,19 +151,7 @@ public class PyClassElementType extends PyStubElementType final String docString = pyClassStub.getDocString(); dataStream.writeUTFFast(docString != null ? docString : ""); - serializeCustomStub(pyClassStub, dataStream); - } - - private static void serializeCustomStub(@NotNull PyClassStub stub, @NotNull StubOutputStream stream) throws IOException { - final PyCustomClassStub customStub = stub.getCustomStub(PyCustomClassStub.class); - - final boolean hasCustomStub = customStub != null; - stream.writeBoolean(hasCustomStub); - - if (hasCustomStub) { - stream.writeName(customStub.getTypeClass().getCanonicalName()); - customStub.serialize(stream); - } + serializeCustomStub(pyClassStub.getCustomStub(PyCustomClassStub.class), dataStream); } @Override @@ -212,21 +191,6 @@ public class PyClassElementType extends PyStubElementType getStubElementType(), customStub); } - @Nullable - private PyCustomClassStub deserializeCustomStub(@NotNull StubInputStream stream) throws IOException { - if (stream.readBoolean()) { - final String typeName = stream.readNameString(); - for (PyCustomClassStubType type : getCustomStubTypes()) { - if (type.getClass().getCanonicalName().equals(typeName)) { - return type.deserializeStub(stream); - } - } - throw new IOException("Unknown custom class stub type " + typeName); - } - - return null; - } - @Override public void indexStub(@NotNull final PyClassStub stub, @NotNull final IndexSink sink) { final String name = stub.getName(); @@ -253,10 +217,8 @@ public class PyClassElementType extends PyStubElementType } @NotNull - private List getCustomStubTypes() { - if (myCustomStubTypes == null) { - myCustomStubTypes = PyCustomClassStubType.EP_NAME.getExtensionList(); - } - return myCustomStubTypes; + @Override + public List> getExtensions() { + return PyCustomClassStubType.EP_NAME.getExtensionList(); } } \ No newline at end of file diff --git a/python/src/com/jetbrains/python/psi/impl/stubs/PyTargetExpressionElementType.java b/python/src/com/jetbrains/python/psi/impl/stubs/PyTargetExpressionElementType.java index 3fd49ef02d75..d9366c5bd8e7 100644 --- a/python/src/com/jetbrains/python/psi/impl/stubs/PyTargetExpressionElementType.java +++ b/python/src/com/jetbrains/python/psi/impl/stubs/PyTargetExpressionElementType.java @@ -28,8 +28,9 @@ import java.util.List; /** * @author yole */ -public class PyTargetExpressionElementType extends PyStubElementType { - private List myCustomStubTypes; +public class PyTargetExpressionElementType extends PyStubElementType + implements + PyCustomizableStubElementType> { public PyTargetExpressionElementType() { super("TARGET_EXPRESSION"); @@ -39,13 +40,6 @@ public class PyTargetExpressionElementType extends PyStubElementType getCustomStubTypes() { - if (myCustomStubTypes == null) { - myCustomStubTypes = CustomTargetExpressionStubType.EP_NAME.getExtensionList(); - } - return myCustomStubTypes; - } - @Override @NotNull public PsiElement createElement(@NotNull final ASTNode node) { @@ -66,12 +60,11 @@ public class PyTargetExpressionElementType extends PyStubElementType> getExtensions() { + return CustomTargetExpressionStubType.EP_NAME.getExtensionList(); + } } diff --git a/python/src/com/jetbrains/python/psi/impl/stubs/PyTypingNewTypeStubType.kt b/python/src/com/jetbrains/python/psi/impl/stubs/PyTypingNewTypeStubType.kt index bcb41e33bfa7..5469b3cf9b96 100644 --- a/python/src/com/jetbrains/python/psi/impl/stubs/PyTypingNewTypeStubType.kt +++ b/python/src/com/jetbrains/python/psi/impl/stubs/PyTypingNewTypeStubType.kt @@ -8,12 +8,11 @@ import com.jetbrains.python.psi.stubs.PyTypingNewTypeStub class PyTypingNewTypeStubType : CustomTargetExpressionStubType() { - override fun createStub(psi: PyTargetExpression?): PyTypingNewTypeStub? { + override fun createStub(psi: PyTargetExpression): PyTypingNewTypeStub? { return PyTypingNewTypeStubImpl.create(psi) } - override fun deserializeStub(stream: StubInputStream?): PyTypingNewTypeStub? { + override fun deserializeStub(stream: StubInputStream): PyTypingNewTypeStub? { return PyTypingNewTypeStubImpl.deserialize(stream) } - } \ No newline at end of file