Skip to content

Commit

Permalink
Merge pull request #2369 from Haehnchen/feature/php-instanceof
Browse files Browse the repository at this point in the history
replace "isConvertibleFrom" instance of check with PhpClassHierarchyUtils.processSupers
  • Loading branch information
Haehnchen authored Apr 29, 2024
2 parents e0c36c7 + ef9ee04 commit ffb8557
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import com.intellij.lang.ASTNode;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.patterns.ElementPattern;
import com.intellij.patterns.PatternCondition;
import com.intellij.patterns.PlatformPatterns;
Expand Down Expand Up @@ -48,8 +47,8 @@
import fr.adrienbrault.idea.symfony2plugin.dic.MethodReferenceBag;
import fr.adrienbrault.idea.symfony2plugin.util.psi.PsiElementAssertUtil;
import kotlin.Pair;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

Expand Down Expand Up @@ -788,24 +787,17 @@ static public PhpClass getClassInterface(Project project, @NotNull String classN
* @param expectedClass eg DateTimeInterface
*/
public static boolean isInstanceOf(@NotNull PhpClass subjectClass, @NotNull PhpClass expectedClass) {
Ref<Boolean> result = new Ref<>(false);

PhpClassHierarchyUtils.processSupers(subjectClass, true, true, superClass -> {
boolean b = StringUtil.equalsIgnoreCase(superClass.getFQN(), expectedClass.getFQN())
|| StringUtil.equalsIgnoreCase(StringUtils.stripStart(superClass.getFQN(), "\\"), StringUtils.stripStart(expectedClass.getFQN(), "\\"));

if (b) {
result.set(true);
}

return !(Boolean)result.get();
});

if (result.get()) {
if (PhpLangUtil.equalsClassNames(subjectClass.getFQN(), expectedClass.getFQN())) {
return true;
}

return new PhpType().add(expectedClass).isConvertibleFrom(new PhpType().add(subjectClass), PhpIndex.getInstance(subjectClass.getProject()));
Ref<Boolean> ref = new Ref<>(false);
PhpClassHierarchyUtils.processSupers(subjectClass, false, true, curClass -> {
ref.set(PhpLangUtil.equalsClassNames(curClass.getFQN(), expectedClass.getFQN()));
return !(Boolean) ref.get();
});

return ref.get();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,25 +118,29 @@ public void testIsInstanceOf() {
Collection<String[]> providers = new ArrayList<>() {{
add(new String[]{"\\Instance\\Of\\Foo", "\\Instance\\Of\\Bar"});
add(new String[]{"\\Instance\\Of\\Foo", "\\Instance\\Of\\Cool"});
add(new String[]{"\\Instance\\Of\\Foo", "\\Instance\\Of\\Apple"});
add(new String[]{"\\Instance\\Of\\Car", "\\Instance\\Of\\Bar"});
add(new String[]{"\\Instance\\Of\\Car", "\\Instance\\Of\\Foo"});
add(new String[]{"\\Instance\\Of\\Car", "\\Instance\\Of\\Cool"});
add(new String[]{"\\Instance\\Of\\Car", "\\Instance\\Of\\Car"});

// backslash
add(new String[]{"Instance\\Of\\Car", "Instance\\Of\\Cool"});
add(new String[]{"Instance\\Of\\Car", "\\Instance\\Of\\Cool"});
add(new String[]{"\\Instance\\Of\\Car", "Instance\\Of\\Cool"});

// dups
add(new String[]{"\\Instance\\Of\\Car", "Instance\\Of\\Apple"});
add(new String[]{"\\Instance\\Of\\Foo", "Instance\\Of\\Apple"});
add(new String[]{"\\Instance\\Of\\Apple", "Instance\\Of\\Apple"});
}};

for (String[] provider : providers) {
assertTrue(PhpElementsUtil.isInstanceOf(getProject(), provider[0], provider[1]));
assertTrue(PhpElementsUtil.isInstanceOf(PhpElementsUtil.getClassInterface(getProject(), provider[0]), provider[1]));
String errorMessage = "'%s' not instance of '%s'".formatted(provider[0], provider[1]);

assertTrue(PhpElementsUtil.isInstanceOf(
assertTrue(errorMessage, PhpElementsUtil.isInstanceOf(getProject(), provider[0], provider[1]));
assertTrue(errorMessage, PhpElementsUtil.isInstanceOf(PhpElementsUtil.getClassInterface(getProject(), provider[0]), provider[1]));

assertTrue(errorMessage, PhpElementsUtil.isInstanceOf(
PhpElementsUtil.getClassInterface(getProject(), provider[0]),
PhpElementsUtil.getClassInterface(getProject(), provider[1])
));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,10 @@
<?php

namespace Instance\Of {
//duplicates
class Car implements \DateTime{}
class Foo implements \DateTime{}


class Foo extends Cool implements Bar{}
interface Bar {}
class Car extends Foo{}
interface Bar extends Apple {}
class Car extends Foo implements Apple{}
class Cool{}

//duplicates
class Car implements Apple{}
class Foo implements Apple{}

interface Apple{}
}

0 comments on commit ffb8557

Please sign in to comment.