mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Reduce code duplication in python custom stubs (PY-29929)
This commit is contained in:
@@ -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<Psi extends PyElement, Stub extends PyCustomStub, StubType extends PyCustomStubType<Psi, ? extends Stub>> {
|
||||
|
||||
@NotNull
|
||||
List<StubType> 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;
|
||||
}
|
||||
}
|
||||
+1
-8
@@ -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<? extends CustomTargetExpressionStubType> getTypeClass();
|
||||
void serialize(StubOutputStream stream) throws IOException;
|
||||
public interface CustomTargetExpressionStub extends PyCustomStub<CustomTargetExpressionStubType> {
|
||||
|
||||
@Nullable
|
||||
QualifiedName getCalleeName();
|
||||
|
||||
+4
-11
@@ -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<T extends CustomTargetExpressionStub> {
|
||||
public static final ExtensionPointName<CustomTargetExpressionStubType> EP_NAME = ExtensionPointName.create("Pythonid.customTargetExpressionStubType");
|
||||
public abstract class CustomTargetExpressionStubType<T extends CustomTargetExpressionStub>
|
||||
implements PyCustomStubType<PyTargetExpression, T> {
|
||||
|
||||
@Nullable
|
||||
public abstract T createStub(PyTargetExpression psi);
|
||||
|
||||
@Nullable
|
||||
public abstract T deserializeStub(StubInputStream stream) throws IOException;
|
||||
public static final ExtensionPointName<CustomTargetExpressionStubType<? extends CustomTargetExpressionStub>> EP_NAME =
|
||||
ExtensionPointName.create("Pythonid.customTargetExpressionStubType");
|
||||
|
||||
public void indexStub(PyTargetExpressionStub stub, IndexSink sink) {
|
||||
}
|
||||
|
||||
@@ -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<? extends PyCustomClassStubType> 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<PyCustomClassStubType> {
|
||||
}
|
||||
|
||||
@@ -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<T extends PyCustomClassStub> implements PyCustomStubType<PyClass, T> {
|
||||
|
||||
public abstract class PyCustomClassStubType<T extends PyCustomClassStub> {
|
||||
|
||||
public static final ExtensionPointName<PyCustomClassStubType> 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<PyCustomClassStubType<? extends PyCustomClassStub>> EP_NAME =
|
||||
ExtensionPointName.create("Pythonid.customClassStubType");
|
||||
}
|
||||
|
||||
@@ -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<CustomStubType extends PyCustomStubType> {
|
||||
|
||||
/**
|
||||
* @return type class to distinguish one custom stub from another.
|
||||
*/
|
||||
@NotNull
|
||||
Class<? extends CustomStubType> getTypeClass();
|
||||
|
||||
/**
|
||||
* @param stream stream to serialize {@code this} stub
|
||||
* @throws IOException
|
||||
* @see PyCustomStubType#deserializeStub(StubInputStream)
|
||||
*/
|
||||
void serialize(@NotNull StubOutputStream stream) throws IOException;
|
||||
}
|
||||
@@ -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<Psi extends PyElement, Stub extends PyCustomStub> {
|
||||
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
@@ -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<PyClassStub, PyClass> {
|
||||
|
||||
@Nullable
|
||||
private List<PyCustomClassStubType> myCustomStubTypes;
|
||||
public class PyClassElementType extends PyStubElementType<PyClassStub, PyClass>
|
||||
implements PyCustomizableStubElementType<PyClass, PyCustomClassStub, PyCustomClassStubType<? extends PyCustomClassStub>> {
|
||||
|
||||
public PyClassElementType() {
|
||||
this("CLASS_DECLARATION");
|
||||
@@ -52,12 +49,6 @@ public class PyClassElementType extends PyStubElementType<PyClassStub, PyClass>
|
||||
@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<PyClassStub, PyClass>
|
||||
psi.getOwnSlots(),
|
||||
PyPsiUtils.strValue(psi.getDocStringExpression()),
|
||||
getStubElementType(),
|
||||
customStub);
|
||||
createCustomStub(psi));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -160,19 +151,7 @@ public class PyClassElementType extends PyStubElementType<PyClassStub, PyClass>
|
||||
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<PyClassStub, PyClass>
|
||||
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<PyClassStub, PyClass>
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<PyCustomClassStubType> getCustomStubTypes() {
|
||||
if (myCustomStubTypes == null) {
|
||||
myCustomStubTypes = PyCustomClassStubType.EP_NAME.getExtensionList();
|
||||
}
|
||||
return myCustomStubTypes;
|
||||
@Override
|
||||
public List<PyCustomClassStubType<? extends PyCustomClassStub>> getExtensions() {
|
||||
return PyCustomClassStubType.EP_NAME.getExtensionList();
|
||||
}
|
||||
}
|
||||
@@ -28,8 +28,9 @@ import java.util.List;
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class PyTargetExpressionElementType extends PyStubElementType<PyTargetExpressionStub, PyTargetExpression> {
|
||||
private List<CustomTargetExpressionStubType> myCustomStubTypes;
|
||||
public class PyTargetExpressionElementType extends PyStubElementType<PyTargetExpressionStub, PyTargetExpression>
|
||||
implements
|
||||
PyCustomizableStubElementType<PyTargetExpression, CustomTargetExpressionStub, CustomTargetExpressionStubType<? extends CustomTargetExpressionStub>> {
|
||||
|
||||
public PyTargetExpressionElementType() {
|
||||
super("TARGET_EXPRESSION");
|
||||
@@ -39,13 +40,6 @@ public class PyTargetExpressionElementType extends PyStubElementType<PyTargetExp
|
||||
super(debugName);
|
||||
}
|
||||
|
||||
private List<CustomTargetExpressionStubType> 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<PyTargetExp
|
||||
final String typeComment = psi.getTypeCommentAnnotation();
|
||||
final String annotation = psi.getAnnotationValue();
|
||||
|
||||
for (CustomTargetExpressionStubType customStubType : getCustomStubTypes()) {
|
||||
CustomTargetExpressionStub customStub = customStubType.createStub(psi);
|
||||
if (customStub != null) {
|
||||
return new PyTargetExpressionStubImpl(name, docString, typeComment, annotation, psi.hasAssignedValue(), customStub, parentStub);
|
||||
}
|
||||
CustomTargetExpressionStub customStub = createCustomStub(psi);
|
||||
if (customStub != null) {
|
||||
return new PyTargetExpressionStubImpl(name, docString, typeComment, annotation, psi.hasAssignedValue(), customStub, parentStub);
|
||||
}
|
||||
|
||||
PyTargetExpressionStub.InitializerType initializerType = PyTargetExpressionStub.InitializerType.Other;
|
||||
QualifiedName initializer = null;
|
||||
if (assignedValue instanceof PyReferenceExpression) {
|
||||
@@ -100,8 +93,7 @@ public class PyTargetExpressionElementType extends PyStubElementType<PyTargetExp
|
||||
stream.writeBoolean(stub.hasAssignedValue());
|
||||
final CustomTargetExpressionStub customStub = stub.getCustomStub(CustomTargetExpressionStub.class);
|
||||
if (customStub != null) {
|
||||
stream.writeName(customStub.getTypeClass().getCanonicalName());
|
||||
customStub.serialize(stream);
|
||||
serializeCustomStub(customStub, stream);
|
||||
}
|
||||
else {
|
||||
QualifiedName.serialize(stub.getInitializer(), stream);
|
||||
@@ -122,14 +114,8 @@ public class PyTargetExpressionElementType extends PyStubElementType<PyTargetExp
|
||||
String annotation = stream.readNameString();
|
||||
final boolean hasAssignedValue = stream.readBoolean();
|
||||
if (initializerType == PyTargetExpressionStub.InitializerType.Custom) {
|
||||
final String typeName = stream.readNameString();
|
||||
for(CustomTargetExpressionStubType type: getCustomStubTypes()) {
|
||||
if (type.getClass().getCanonicalName().equals(typeName)) {
|
||||
CustomTargetExpressionStub stub = type.deserializeStub(stream);
|
||||
return new PyTargetExpressionStubImpl(name, docString, typeComment, annotation, hasAssignedValue, stub, parentStub);
|
||||
}
|
||||
}
|
||||
throw new IOException("Unknown custom stub type " + typeName);
|
||||
CustomTargetExpressionStub stub = deserializeCustomStub(stream);
|
||||
return new PyTargetExpressionStubImpl(name, docString, typeComment, annotation, hasAssignedValue, stub, parentStub);
|
||||
}
|
||||
QualifiedName initializer = QualifiedName.deserialize(stream);
|
||||
boolean isQualified = stream.readBoolean();
|
||||
@@ -167,8 +153,14 @@ public class PyTargetExpressionElementType extends PyStubElementType<PyTargetExp
|
||||
sink.occurrence(PyVariableNameIndex.KEY, name);
|
||||
}
|
||||
}
|
||||
for (CustomTargetExpressionStubType stubType : getCustomStubTypes()) {
|
||||
for (CustomTargetExpressionStubType stubType : getExtensions()) {
|
||||
stubType.indexStub(stub, sink);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<CustomTargetExpressionStubType<? extends CustomTargetExpressionStub>> getExtensions() {
|
||||
return CustomTargetExpressionStubType.EP_NAME.getExtensionList();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,12 +8,11 @@ import com.jetbrains.python.psi.stubs.PyTypingNewTypeStub
|
||||
|
||||
class PyTypingNewTypeStubType : CustomTargetExpressionStubType<PyTypingNewTypeStub>() {
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user