mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
TypeConstraint: minor fixes and simplifications
GitOrigin-RevId: f1a5c38d1af22d1cc64e0a7a1bae2d67f396ffa5
This commit is contained in:
committed by
intellij-monorepo-bot
parent
79728cf999
commit
5d5ba9e0ef
+15
-11
@@ -173,7 +173,14 @@ public interface TypeConstraint {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return stream of supertypes (except java.lang.Object)
|
||||
* @return true if instances of this type can exist (i.e. the type is not abstract).
|
||||
*/
|
||||
default boolean canBeInstantiated() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return stream of supertypes
|
||||
*/
|
||||
StreamEx<Exact> superTypes();
|
||||
|
||||
@@ -218,12 +225,13 @@ public interface TypeConstraint {
|
||||
|
||||
@Override
|
||||
default TypeConstraint tryNegate() {
|
||||
return isFinal() ? new Constrained(Collections.emptySet(), Collections.singleton(this)) : null;
|
||||
return isFinal() ? notInstanceOf() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a constraint that represents objects not only of this type but also of any subtypes. May return self if the type is final.
|
||||
*/
|
||||
@NotNull
|
||||
default TypeConstraint instanceOf() {
|
||||
if (isFinal()) return this;
|
||||
return new Constrained(Collections.singleton(this), Collections.emptySet());
|
||||
@@ -232,14 +240,10 @@ public interface TypeConstraint {
|
||||
/**
|
||||
* @return a constraint that represents objects that are not instanceof this type
|
||||
*/
|
||||
@NotNull
|
||||
default TypeConstraint notInstanceOf() {
|
||||
return new Constrained(Collections.emptySet(), Collections.singleton(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if instances of this type can exist (i.e. the type is not abstract).
|
||||
*/
|
||||
boolean canBeInstantiated();
|
||||
|
||||
@Override
|
||||
default String toShortString() {
|
||||
@@ -277,10 +281,10 @@ public interface TypeConstraint {
|
||||
@Override
|
||||
public TypeConstraint tryNegate() {
|
||||
if (myInstanceOf.size() == 1 && myNotInstanceOf.isEmpty()) {
|
||||
return new Constrained(Collections.emptySet(), Collections.singleton(myInstanceOf.iterator().next()));
|
||||
return myInstanceOf.iterator().next().notInstanceOf();
|
||||
}
|
||||
if (myNotInstanceOf.size() == 1 && myInstanceOf.isEmpty()) {
|
||||
return new Constrained(Collections.singleton(myNotInstanceOf.iterator().next()), Collections.emptySet());
|
||||
return myNotInstanceOf.iterator().next().instanceOf();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -314,10 +318,10 @@ public interface TypeConstraint {
|
||||
}
|
||||
TypeConstraint constraint = TypeConstraints.TOP;
|
||||
for (Exact type: instanceOfTypes) {
|
||||
constraint = constraint.meet(new Constrained(Collections.singleton(type), Collections.emptySet()));
|
||||
constraint = constraint.meet(type.instanceOf());
|
||||
}
|
||||
for (Exact type: notTypes) {
|
||||
constraint = constraint.meet(new Constrained(Collections.emptySet(), Collections.singleton(type)));
|
||||
constraint = constraint.meet(type.notInstanceOf());
|
||||
}
|
||||
return constraint;
|
||||
}
|
||||
|
||||
+44
-191
@@ -18,64 +18,38 @@ public class TypeConstraints {
|
||||
* Top constraint (no restriction; any non-primitive value satisfies this)
|
||||
*/
|
||||
public static final TypeConstraint TOP = new TypeConstraint() {
|
||||
@NotNull
|
||||
@Override
|
||||
public TypeConstraint join(@NotNull TypeConstraint other) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public TypeConstraint meet(@NotNull TypeConstraint other) {
|
||||
return other;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuperConstraintOf(@NotNull TypeConstraint other) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeConstraint tryNegate() {
|
||||
return BOTTOM;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return "";
|
||||
}
|
||||
@NotNull @Override public TypeConstraint join(@NotNull TypeConstraint other) { return this;}
|
||||
@NotNull @Override public TypeConstraint meet(@NotNull TypeConstraint other) { return other; }
|
||||
@Override public boolean isSuperConstraintOf(@NotNull TypeConstraint other) { return true; }
|
||||
@Override public TypeConstraint tryNegate() { return BOTTOM; }
|
||||
@Override public String toString() { return ""; }
|
||||
};
|
||||
/**
|
||||
* Bottom constraint (no actual type satisfies this)
|
||||
*/
|
||||
public static final TypeConstraint BOTTOM = new TypeConstraint() {
|
||||
@NotNull
|
||||
@Override
|
||||
public TypeConstraint join(@NotNull TypeConstraint other) {
|
||||
return other;
|
||||
}
|
||||
@NotNull @Override public TypeConstraint join(@NotNull TypeConstraint other) { return other;}
|
||||
@NotNull @Override public TypeConstraint meet(@NotNull TypeConstraint other) { return this;}
|
||||
@Override public boolean isSuperConstraintOf(@NotNull TypeConstraint other) { return other == this; }
|
||||
@Override public TypeConstraint tryNegate() { return TOP; }
|
||||
@Override public String toString() { return "<impossible type>"; }
|
||||
};
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public TypeConstraint meet(@NotNull TypeConstraint other) {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Exactly java.lang.Object class
|
||||
*/
|
||||
public static final TypeConstraint.Exact EXACTLY_OBJECT = new TypeConstraint.Exact() {
|
||||
@Override public StreamEx<Exact> superTypes() { return StreamEx.empty();}
|
||||
@Override public boolean isFinal() { return false;}
|
||||
@Override public boolean isAssignableFrom(@NotNull Exact other) { return true;}
|
||||
@Override public boolean isConvertibleFrom(@NotNull Exact other) { return true;}
|
||||
@NotNull @Override public TypeConstraint instanceOf() { return TOP;}
|
||||
@NotNull @Override public TypeConstraint notInstanceOf() { return BOTTOM;}
|
||||
@Override public String toString() { return CommonClassNames.JAVA_LANG_OBJECT;}
|
||||
|
||||
@Override
|
||||
public TypeConstraint tryNegate() {
|
||||
return TOP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuperConstraintOf(@NotNull TypeConstraint other) {
|
||||
return other == this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return "<impossible type>";
|
||||
public PsiType getPsiType(Project project) {
|
||||
return JavaPsiFacade.getElementFactory(project).createTypeByFQClassName(CommonClassNames.JAVA_LANG_OBJECT);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -120,20 +94,6 @@ public class TypeConstraints {
|
||||
return BOTTOM;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param superClass a superclass
|
||||
* @param tag a tag to distinguish subclasses; subclasses of the same class with the same tag are considered the same
|
||||
* @return an unknown exact final direct subclass of given class or interface.
|
||||
* Useful in rare cases when the corresponding subclass class object cannot be found.
|
||||
*/
|
||||
public static TypeConstraint exactSubClassOf(@NotNull PsiClass superClass, @NotNull Object tag) {
|
||||
TypeConstraint.Exact exactSuperClass = exactClass(superClass);
|
||||
if (exactSuperClass instanceof ExactClass) {
|
||||
return new ExactSubClass((ExactClass)exactSuperClass, tag);
|
||||
}
|
||||
return exactSuperClass.instanceOf();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param type PsiType
|
||||
* @return a constraint for the object whose type is the supplied type or any subtype
|
||||
@@ -151,7 +111,7 @@ public class TypeConstraints {
|
||||
if (exact == null) {
|
||||
return new Unresolved(type.getCanonicalText()).instanceOf();
|
||||
}
|
||||
result = result.meet(new TypeConstraint.Constrained(Collections.singleton(exact), Collections.emptySet()));
|
||||
result = result.meet(exact.instanceOf());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -162,21 +122,6 @@ public class TypeConstraints {
|
||||
return exact.instanceOf();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param type PsiType
|
||||
* @return a constraint for the object whose type is not the supplied type or any of its subtypes
|
||||
*/
|
||||
@NotNull
|
||||
@Contract(pure = true)
|
||||
public static TypeConstraint notInstanceOf(@NotNull PsiType type) {
|
||||
type = normalizeType(type);
|
||||
TypeConstraint.Exact exact = createExact(type);
|
||||
if (exact != null) {
|
||||
return new TypeConstraint.Constrained(Collections.emptySet(), Collections.singleton(exact));
|
||||
}
|
||||
return TOP;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static PsiType normalizeType(@NotNull PsiType psiType) {
|
||||
if (psiType instanceof PsiArrayType) {
|
||||
@@ -224,12 +169,15 @@ public class TypeConstraints {
|
||||
|
||||
@NotNull
|
||||
private static TypeConstraint.Exact exactClass(@NotNull PsiClass psiClass) {
|
||||
if (psiClass.isInterface()) {
|
||||
if (CommonClassNames.JAVA_LANG_CLONEABLE.equals(psiClass.getQualifiedName())) {
|
||||
return ArraySuperInterface.CLONEABLE;
|
||||
}
|
||||
if (CommonClassNames.JAVA_IO_SERIALIZABLE.equals(psiClass.getQualifiedName())) {
|
||||
return ArraySuperInterface.SERIALIZABLE;
|
||||
String name = psiClass.getQualifiedName();
|
||||
if (name != null) {
|
||||
switch (name) {
|
||||
case CommonClassNames.JAVA_LANG_OBJECT:
|
||||
return EXACTLY_OBJECT;
|
||||
case CommonClassNames.JAVA_LANG_CLONEABLE:
|
||||
return ArraySuperInterface.CLONEABLE;
|
||||
case CommonClassNames.JAVA_IO_SERIALIZABLE:
|
||||
return ArraySuperInterface.SERIALIZABLE;
|
||||
}
|
||||
}
|
||||
return new ExactClass(psiClass);
|
||||
@@ -268,7 +216,7 @@ public class TypeConstraints {
|
||||
|
||||
@Override
|
||||
public StreamEx<Exact> superTypes() {
|
||||
return StreamEx.of(ArraySuperInterface.values());
|
||||
return StreamEx.<Exact>of(ArraySuperInterface.values()).append(EXACTLY_OBJECT);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -280,11 +228,6 @@ public class TypeConstraints {
|
||||
public boolean isConvertibleFrom(@NotNull Exact other) {
|
||||
return other.equals(this) || other.isAssignableFrom(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeInstantiated() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private enum ArraySuperInterface implements TypeConstraint.Exact {
|
||||
@@ -315,7 +258,7 @@ public class TypeConstraints {
|
||||
|
||||
@Override
|
||||
public StreamEx<Exact> superTypes() {
|
||||
return StreamEx.empty();
|
||||
return StreamEx.of(EXACTLY_OBJECT);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -325,9 +268,6 @@ public class TypeConstraints {
|
||||
if (other instanceof ExactClass) {
|
||||
return InheritanceUtil.isInheritor(((ExactClass)other).myClass, myReference);
|
||||
}
|
||||
if (other instanceof ExactSubClass) {
|
||||
return isAssignableFrom(((ExactSubClass)other).mySuper);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -358,12 +298,7 @@ public class TypeConstraints {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(myClass.getQualifiedName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeConstraint instanceOf() {
|
||||
return isObject() ? TOP : Exact.super.instanceOf();
|
||||
return Objects.hashCode(myClass.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -398,39 +333,30 @@ public class TypeConstraints {
|
||||
@Override
|
||||
public StreamEx<Exact> superTypes() {
|
||||
List<Exact> superTypes = new ArrayList<>();
|
||||
InheritanceUtil.processSupers(myClass, false, t -> {
|
||||
if (!CommonClassNames.JAVA_LANG_OBJECT.equals(t.getQualifiedName())) {
|
||||
superTypes.add(exactClass(t));
|
||||
}
|
||||
return true;
|
||||
});
|
||||
InheritanceUtil.processSupers(myClass, false, t -> superTypes.add(exactClass(t)));
|
||||
return StreamEx.of(superTypes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAssignableFrom(@NotNull Exact other) {
|
||||
if (equals(other) || isObject() || other instanceof Unresolved) return true;
|
||||
if (equals(other) || other instanceof Unresolved) return true;
|
||||
if (other instanceof ExactClass) {
|
||||
String name = myClass.getQualifiedName();
|
||||
if (name == null) return false;
|
||||
return InheritanceUtil.isInheritor(((ExactClass)other).myClass, name);
|
||||
}
|
||||
if (other instanceof ExactSubClass) {
|
||||
return isAssignableFrom(((ExactSubClass)other).mySuper);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConvertibleFrom(@NotNull Exact other) {
|
||||
if (equals(other) || isObject() || other instanceof Unresolved) return true;
|
||||
if (equals(other) || other instanceof Unresolved || other == EXACTLY_OBJECT) return true;
|
||||
if (other instanceof ArraySuperInterface) {
|
||||
if (myClass.isInterface()) return true;
|
||||
if (!myClass.hasModifierProperty(PsiModifier.FINAL)) return true;
|
||||
return InheritanceUtil.isInheritor(myClass, ((ArraySuperInterface)other).myReference);
|
||||
}
|
||||
if (other instanceof ExactClass) {
|
||||
if (((ExactClass)other).isObject()) return true;
|
||||
PsiClass otherClass = ((ExactClass)other).myClass;
|
||||
if (myClass.isInterface() && otherClass.isInterface()) return true;
|
||||
if (myClass.isInterface() && !otherClass.hasModifierProperty(PsiModifier.FINAL)) return true;
|
||||
@@ -440,69 +366,8 @@ public class TypeConstraints {
|
||||
return otherName != null && InheritanceUtil.isInheritor(myClass, otherName) ||
|
||||
myName != null && InheritanceUtil.isInheritor(otherClass, myName);
|
||||
}
|
||||
if (other instanceof ExactSubClass) {
|
||||
return isAssignableFrom(((ExactSubClass)other).mySuper);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isObject() {
|
||||
return CommonClassNames.JAVA_LANG_OBJECT.equals(myClass.getQualifiedName());
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ExactSubClass implements TypeConstraint.Exact {
|
||||
private final @NotNull ExactClass mySuper;
|
||||
private final @NotNull Object myTag;
|
||||
|
||||
ExactSubClass(@NotNull ExactClass aSuper, @NotNull Object tag) {
|
||||
mySuper = aSuper;
|
||||
myTag = tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj == this ||
|
||||
obj instanceof ExactSubClass &&
|
||||
mySuper.equals(((ExactSubClass)obj).mySuper) &&
|
||||
myTag.equals(((ExactSubClass)obj).myTag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return mySuper.hashCode() * 31 + myTag.hashCode();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return "unknown subclass of " + mySuper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinal() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StreamEx<Exact> superTypes() {
|
||||
return mySuper.superTypes().prepend(mySuper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAssignableFrom(@NotNull Exact other) {
|
||||
return equals(other);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConvertibleFrom(@NotNull Exact other) {
|
||||
return other.isAssignableFrom(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeInstantiated() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ExactArray implements TypeConstraint.Exact {
|
||||
@@ -537,8 +402,7 @@ public class TypeConstraints {
|
||||
|
||||
@Override
|
||||
public StreamEx<Exact> superTypes() {
|
||||
return myComponent instanceof ExactArray || myComponent instanceof PrimitiveArray ? myComponent.superTypes()
|
||||
: myComponent.superTypes().<Exact>map(ExactArray::new).append(ArraySuperInterface.values());
|
||||
return myComponent.superTypes().<Exact>map(ExactArray::new).append(ArraySuperInterface.values()).append(EXACTLY_OBJECT);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -558,11 +422,6 @@ public class TypeConstraints {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeInstantiated() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class Unresolved implements TypeConstraint.Exact {
|
||||
@@ -590,23 +449,17 @@ public class TypeConstraints {
|
||||
|
||||
@Override
|
||||
public StreamEx<Exact> superTypes() {
|
||||
return StreamEx.empty();
|
||||
return StreamEx.of(EXACTLY_OBJECT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAssignableFrom(@NotNull Exact other) {
|
||||
return other instanceof Unresolved || other instanceof ExactClass || other instanceof ExactSubClass;
|
||||
return other instanceof Unresolved || other instanceof ExactClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConvertibleFrom(@NotNull Exact other) {
|
||||
return other instanceof Unresolved || other instanceof ExactClass || other instanceof ExactSubClass ||
|
||||
other instanceof ArraySuperInterface;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeInstantiated() {
|
||||
return true;
|
||||
return other instanceof Unresolved || other instanceof ExactClass || other instanceof ArraySuperInterface;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user