use of com.jetbrains.php.lang.psi.elements.ClassReference in project phpinspectionsea by kalessil.
the class IsIterableCanBeUsedInspector method buildVisitor.
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly) {
return new BasePhpElementVisitor() {
@Override
public void visitPhpFunctionCall(@NotNull FunctionReference reference) {
final String functionName = reference.getName();
if (functionName != null && functionName.equals("is_array")) {
final boolean isTargetVersion = PhpLanguageLevel.get(holder.getProject()).atLeast(PhpLanguageLevel.PHP710);
if (isTargetVersion) {
final PsiElement[] arguments = reference.getParameters();
final PsiElement parent = reference.getParent();
if (parent instanceof BinaryExpression && arguments.length == 1) {
final BinaryExpression binary = (BinaryExpression) parent;
final IElementType operation = binary.getOperationType();
if (operation == PhpTokenTypes.opOR) {
/* find the high-level binary expression */
BinaryExpression context = binary;
while (context instanceof BinaryExpression) {
PsiElement up = context.getParent();
while (up instanceof ParenthesizedExpression) {
up = up.getParent();
}
if (up instanceof BinaryExpression && ((BinaryExpression) up).getOperationType() == PhpTokenTypes.opOR) {
context = (BinaryExpression) up;
} else {
break;
}
}
/* check the pattern */
final List<PsiElement> fragments = this.extract(context, PhpTokenTypes.opOR);
if (!fragments.isEmpty()) {
if (fragments.size() > 1) {
for (final PsiElement fragment : fragments) {
if (fragment != reference && fragment instanceof BinaryExpression) {
final BinaryExpression candidate = (BinaryExpression) fragment;
if (candidate.getOperationType() == PhpTokenTypes.kwINSTANCEOF) {
final PsiElement clazz = candidate.getRightOperand();
if (clazz instanceof ClassReference && "Traversable".equals(((ClassReference) clazz).getName())) {
final PsiElement subject = candidate.getLeftOperand();
if (subject != null && OpenapiEquivalenceUtil.areEqual(subject, arguments[0])) {
final String argument = subject.getText();
holder.registerProblem(reference, String.format(MessagesPresentationUtil.prefixWithEa(message), argument, argument, argument));
break;
}
}
}
}
}
}
fragments.clear();
}
}
}
}
}
}
@NotNull
private List<PsiElement> extract(@NotNull BinaryExpression binary, @Nullable IElementType operator) {
final List<PsiElement> result = new ArrayList<>();
if (binary.getOperationType() == operator) {
Stream.of(binary.getLeftOperand(), binary.getRightOperand()).filter(Objects::nonNull).map(ExpressionSemanticUtil::getExpressionTroughParenthesis).forEach(expression -> {
if (expression instanceof BinaryExpression) {
result.addAll(this.extract((BinaryExpression) expression, operator));
} else {
result.add(expression);
}
});
} else {
result.add(binary);
}
return result;
}
};
}
use of com.jetbrains.php.lang.psi.elements.ClassReference in project phpinspectionsea by kalessil.
the class InstanceOfTraitStrategy method apply.
public static boolean apply(@NotNull BinaryExpression expression, @NotNull ProblemsHolder holder) {
/* general structure expectations */
if (expression.getOperationType() != PhpTokenTypes.kwINSTANCEOF) {
return false;
}
final PsiElement right = expression.getRightOperand();
if (!(right instanceof ClassReference) && !(right instanceof ClassConstantReference)) {
return false;
}
/* $this, self, static are referencing to host classes, skip the case */
if (lateBindingSymbols.contains(right.getText())) {
return false;
}
/* getting class from invariant constructs */
PsiElement resolved = null;
if (right instanceof ClassReference) {
resolved = OpenapiResolveUtil.resolveReference((ClassReference) right);
}
if (right instanceof ClassConstantReference) {
final ClassConstantReference ref = (ClassConstantReference) right;
final PsiElement classReference = ref.getClassReference();
final String constantName = ref.getName();
if (null != constantName && constantName.equals("class") && classReference instanceof ClassReference) {
resolved = OpenapiResolveUtil.resolveReference((ClassReference) classReference);
}
}
/* analysis itself */
if (resolved instanceof PhpClass && ((PhpClass) resolved).isTrait()) {
holder.registerProblem(expression, MessagesPresentationUtil.prefixWithEa(message));
return true;
}
return false;
}
use of com.jetbrains.php.lang.psi.elements.ClassReference in project phpinspectionsea by kalessil.
the class ClassReImplementsParentInterfaceInspector method buildVisitor.
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new BasePhpElementVisitor() {
@Override
public void visitPhpClass(@NotNull PhpClass clazz) {
final List<ClassReference> implemented = clazz.getImplementsList().getReferenceElements();
if (!implemented.isEmpty()) {
/* resolve own interfaces an maintain relation to original element */
final Map<PsiElement, PhpClass> ownInterfaces = new LinkedHashMap<>(implemented.size());
for (final ClassReference reference : implemented) {
final PsiElement resolved = OpenapiResolveUtil.resolveReference(reference);
if (resolved instanceof PhpClass) {
ownInterfaces.put(reference, (PhpClass) resolved);
}
}
implemented.clear();
if (!ownInterfaces.isEmpty()) {
/* Case: indirect declaration duplication (parent already implements) */
final PhpClass parent = OpenapiResolveUtil.resolveSuperClass(clazz);
if (parent != null) {
final Set<PhpClass> inherited = InterfacesExtractUtil.getCrawlInheritanceTree(parent, false);
if (!inherited.isEmpty()) {
final Set<PsiElement> processed = new HashSet<>();
for (final Map.Entry<PsiElement, PhpClass> entry : ownInterfaces.entrySet()) {
final PhpClass ownInterface = entry.getValue();
if (inherited.contains(ownInterface) && processed.add(entry.getKey())) {
holder.registerProblem(entry.getKey(), String.format(MessagesPresentationUtil.prefixWithEa(patternIndirectDuplication), ownInterface.getFQN(), parent.getFQN()), new TheLocalFix());
}
}
processed.clear();
inherited.clear();
}
}
ownInterfaces.clear();
}
}
}
};
}
use of com.jetbrains.php.lang.psi.elements.ClassReference in project phpinspectionsea by kalessil.
the class ImplicitMagicMethodCallInspector method buildVisitor.
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new BasePhpElementVisitor() {
@Override
public void visitPhpMethodReference(@NotNull MethodReference reference) {
final String methodName = reference.getName();
if (methodName != null && methods.contains(methodName)) {
/* Pattern 1: direct calls ob objects */
final String referenceObject = reference.getFirstChild().getText().trim();
if (!referenceObject.equals("$this") && !this.isTestContext(reference)) {
if (!(reference.getFirstChild() instanceof ClassReference) && !referenceObject.equals("parent")) {
/* __toString is a special case */
if (SUGGEST_USING_STRING_CASTING && methodName.equals("__toString")) {
final String message = patternStringCasting.replace("%o%", referenceObject);
holder.registerProblem(reference, message, new UseStringCastingLocalFix());
return;
}
/* allow calling __toString, as a developer don't want hints on this */
if (!SUGGEST_USING_STRING_CASTING && methodName.equals("__toString")) {
return;
}
/* generally reported cases */
holder.registerProblem(reference, message);
return;
}
/* Pattern 2: internal calls inside class methods */
final Function method = ExpressionSemanticUtil.getScope(reference);
if (null != method && !method.getName().equals(methodName)) {
/* allow __construct inside unserialize */
if (methodName.equals("__construct") && method.getName().equals("unserialize")) {
return;
}
/* allow calling __toString, as a developer don't want hints on this */
if (!SUGGEST_USING_STRING_CASTING && methodName.equals("__toString")) {
return;
}
holder.registerProblem(reference, message);
}
}
}
}
};
}
use of com.jetbrains.php.lang.psi.elements.ClassReference in project idea-php-typo3-plugin by cedricziel.
the class LegacyClassesForIdeQuickFix method applyFix.
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiElement psiElement = descriptor.getPsiElement();
if (DumbService.isDumb(project)) {
showIsInDumpModeMessage(project, psiElement);
return;
}
if (psiElement instanceof ClassReference) {
ClassReference classReference = (ClassReference) psiElement;
String fqn = classReference.getFQN();
if (fqn != null) {
String replacementFQN = LegacyClassesForIDEIndex.findReplacementClass(project, fqn);
if (replacementFQN != null) {
try {
classReference.replace(PhpPsiElementFactory.createClassReference(project, replacementFQN));
} catch (IncorrectOperationException e) {
showErrorMessage(project, "Could not replace class reference", psiElement);
}
}
}
}
}
Aggregations