ClassSymbolImpl extends SymbolImpl implements ClassSymbol { @Override public boolean canBeOrExtend(String fullyQualifiedClassName) { if ("object".equals(fullyQualifiedClassName)) { return true; } return allSuperClasses(true).stream().anyMatch(c -> c.fullyQualifiedName() != null && Objects.equals(fullyQualifiedClassName, c.fullyQualifiedName())) || hasUnresolvedTypeHierarchy(); } ClassSymbolImpl(ClassDef classDef, @Nullable String fullyQualifiedName, PythonFile pythonFile);  ClassSymbolImpl(String name, @Nullable String fullyQualifiedName);  ClassSymbolImpl(String name, @Nullable String fullyQualifiedName, @Nullable LocationInFile definitionLocation,
                         boolean hasDecorators, boolean hasMetaClass, @Nullable String metaclassFQN); @Override List<Symbol> superClasses(); void addSuperClass(Symbol symbol); @Override boolean hasUnresolvedTypeHierarchy(); boolean hasUnresolvedTypeHierarchy(boolean includeAmbiguousSymbols); @Override Set<Symbol> declaredMembers(); @Override Optional<Symbol> resolveMember(String memberName); boolean hasMetaClass(); @Override boolean canHaveMember(String memberName); boolean hasSuperClassWithUnknownMetaClass(); @Override LocationInFile definitionLocation(); @Override boolean isOrExtends(String fullyQualifiedClassName); @Override boolean isOrExtends(ClassSymbol other); @Override boolean canBeOrExtend(String fullyQualifiedClassName); @Override boolean hasDecorators(); void addMembers(Collection<Symbol> members); void setHasSuperClassWithoutSymbol(); void setHasMetaClass(); void setMetaclassFQN(String metaclassFQN); @CheckForNull String metaclassFQN(); @Override void removeUsages();  }
@Test public void canBeOrExtend() { ClassSymbolImpl a = new ClassSymbolImpl("a", "mod1.a"); ClassSymbolImpl b = new ClassSymbolImpl("b", "mod2.b"); a.addSuperClass(b); assertThat(a.canBeOrExtend("a")).isFalse(); assertThat(a.canBeOrExtend("mod1.a")).isTrue(); assertThat(a.canBeOrExtend("mod2.b")).isTrue(); assertThat(a.canBeOrExtend("mod2.x")).isFalse(); ClassSymbolImpl c = new ClassSymbolImpl("c", "mod1.c"); HashSet<Symbol> alternatives = new HashSet<>(); alternatives.add(a); alternatives.add(new ClassSymbolImpl("a", "mod2.a")); AmbiguousSymbol aOrB = AmbiguousSymbolImpl.create(alternatives); c.addSuperClass(aOrB); assertThat(c.canBeOrExtend("mod1.a")).isTrue(); assertThat(c.isOrExtends("mod1.a")).isFalse(); assertThat(c.canBeOrExtend("mod2.a")).isTrue(); assertThat(c.canBeOrExtend("mod3.a")).isFalse(); ClassSymbolImpl d = new ClassSymbolImpl("c", "mod1.c"); d.addSuperClass(aOrB); d.setHasSuperClassWithoutSymbol(); assertThat(d.canBeOrExtend("mod1.a")).isTrue(); assertThat(d.canBeOrExtend("mod2.a")).isTrue(); assertThat(d.canBeOrExtend("mod3.a")).isTrue(); assertThat(new ClassSymbolImpl("foo", "foo").canBeOrExtend("object")).isTrue(); assertThat(a.canBeOrExtend("object")).isTrue(); }