use of com.jetbrains.php.lang.psi.elements.BinaryExpression 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.BinaryExpression in project phpinspectionsea by kalessil.
the class AssertBoolOfComparisonStrategy method apply.
public static boolean apply(@NotNull String function, @NotNull MethodReference reference, @NotNull ProblemsHolder holder) {
final PsiElement[] params = reference.getParameters();
if (params.length > 0 && (function.equals("assertTrue") || function.equals("assertNotTrue") || function.equals("assertFalse") || function.equals("assertNotFalse"))) {
final PsiElement param = ExpressionSemanticUtil.getExpressionTroughParenthesis(params[0]);
if (param instanceof BinaryExpression) {
final BinaryExpression argument = (BinaryExpression) param;
final PsiElement left = argument.getLeftOperand();
final PsiElement right = argument.getRightOperand();
final IElementType operation = argument.getOperationType();
if (left != null && right != null && OpenapiTypesUtil.tsCOMPARE_EQUALITY_OPS.contains(operation)) {
final boolean isMethodInverting = function.equals("assertFalse") || function.equals("assertNotTrue");
final boolean isOperationInverting = operation == PhpTokenTypes.opNOT_EQUAL || operation == PhpTokenTypes.opNOT_IDENTICAL;
final boolean isTypeStrict = operation == PhpTokenTypes.opIDENTICAL || operation == PhpTokenTypes.opNOT_IDENTICAL;
final String replacementMethod = "assert" + (isMethodInverting == isOperationInverting ? "" : "Not") + (isTypeStrict ? "Same" : "Equals");
holder.registerProblem(reference, MessagesPresentationUtil.prefixWithEa(messagePattern.replace("%m%", replacementMethod)), new TheLocalFix(holder.getProject(), replacementMethod, left, right));
return true;
}
}
}
return false;
}
use of com.jetbrains.php.lang.psi.elements.BinaryExpression in project phpinspectionsea by kalessil.
the class AssertRegexStrategy method apply.
public static boolean apply(@NotNull String methodName, @NotNull MethodReference reference, @NotNull ProblemsHolder holder) {
boolean result = false;
if (numberCompareTargets.containsKey(methodName)) {
final PsiElement[] assertionArguments = reference.getParameters();
if (assertionArguments.length >= 2 && OpenapiTypesUtil.isNumber(assertionArguments[0])) {
final boolean isTarget = OpenapiTypesUtil.isFunctionReference(assertionArguments[1]);
if (isTarget) {
final FunctionReference candidate = (FunctionReference) assertionArguments[1];
final String candidateName = candidate.getName();
if (candidateName != null && candidateName.equals("preg_match")) {
final PsiElement[] functionArguments = candidate.getParameters();
if (functionArguments.length == 2) {
final String suggestedAssertion = assertionArguments[0].getText().equals(numberCompareTargets.get(methodName)) ? "assertRegExp" : "assertNotRegExp";
final String[] suggestedArguments = new String[assertionArguments.length];
suggestedArguments[0] = functionArguments[0].getText();
suggestedArguments[1] = functionArguments[1].getText();
if (assertionArguments.length > 2) {
suggestedArguments[2] = assertionArguments[2].getText();
}
holder.registerProblem(reference, String.format(MessagesPresentationUtil.prefixWithEa(messagePattern), suggestedAssertion), new PhpUnitAssertFixer(suggestedAssertion, suggestedArguments));
result = true;
}
}
}
}
} else if (binaryTargets.contains(methodName)) {
final PsiElement[] assertionArguments = reference.getParameters();
if (assertionArguments.length > 0 && assertionArguments[0] instanceof BinaryExpression) {
final BinaryExpression binary = (BinaryExpression) assertionArguments[0];
if (binary.getOperationType() == PhpTokenTypes.opGREATER) {
final PsiElement left = binary.getLeftOperand();
final PsiElement right = binary.getRightOperand();
if (OpenapiTypesUtil.isNumber(right) && OpenapiTypesUtil.isFunctionReference(left)) {
final boolean isTargetNumber = right.getText().equals("0");
if (isTargetNumber) {
final FunctionReference candidate = (FunctionReference) left;
final String candidateName = candidate.getName();
if (candidateName != null && candidateName.equals("preg_match")) {
final PsiElement[] functionArguments = candidate.getParameters();
if (functionArguments.length == 2) {
final String suggestedAssertion = methodName.equals("assertTrue") ? "assertRegExp" : "assertNotRegExp";
final String[] suggestedArguments = new String[assertionArguments.length + 1];
suggestedArguments[0] = functionArguments[0].getText();
suggestedArguments[1] = functionArguments[1].getText();
if (assertionArguments.length > 1) {
suggestedArguments[2] = assertionArguments[1].getText();
}
holder.registerProblem(reference, String.format(MessagesPresentationUtil.prefixWithEa(messagePattern), suggestedAssertion), new PhpUnitAssertFixer(suggestedAssertion, suggestedArguments));
result = true;
}
}
}
}
}
}
}
return result;
}
use of com.jetbrains.php.lang.psi.elements.BinaryExpression in project phpinspectionsea by kalessil.
the class PlainApiUseCheckStrategy method isPregMatchInverted.
private static boolean isPregMatchInverted(@NotNull FunctionReference reference) {
boolean result = false;
final PsiElement parent = reference.getParent();
if (ExpressionSemanticUtil.isUsedAsLogicalOperand(reference)) {
if (parent instanceof UnaryExpression) {
result = OpenapiTypesUtil.is(((UnaryExpression) parent).getOperation(), PhpTokenTypes.opNOT);
}
} else if (parent instanceof BinaryExpression) {
// inverted: < 1, == 0, === 0, != 1, !== 1
// not inverted: > 0, == 1, === 1, != 0, !== 0
final BinaryExpression binary = (BinaryExpression) parent;
final IElementType operator = binary.getOperationType();
if (operator == PhpTokenTypes.opLESS || OpenapiTypesUtil.tsCOMPARE_EQUALITY_OPS.contains(operator)) {
final PsiElement second = OpenapiElementsUtil.getSecondOperand(binary, reference);
if (OpenapiTypesUtil.isNumber(second)) {
final String number = second.getText();
result = operator == PhpTokenTypes.opLESS && number.equals("1") || operator == PhpTokenTypes.opEQUAL && number.equals("0") || operator == PhpTokenTypes.opIDENTICAL && number.equals("0") || operator == PhpTokenTypes.opNOT_EQUAL && number.equals("1") || operator == PhpTokenTypes.opNOT_IDENTICAL && number.equals("1");
}
}
}
return result;
}
use of com.jetbrains.php.lang.psi.elements.BinaryExpression in project phpinspectionsea by kalessil.
the class PlainApiUseCheckStrategy method getPregMatchContext.
private static PsiElement getPregMatchContext(@NotNull FunctionReference reference) {
PsiElement result = reference;
final PsiElement parent = reference.getParent();
if (ExpressionSemanticUtil.isUsedAsLogicalOperand(reference)) {
if (parent instanceof UnaryExpression) {
final UnaryExpression unary = (UnaryExpression) parent;
if (OpenapiTypesUtil.is(unary.getOperation(), PhpTokenTypes.opNOT)) {
result = parent;
}
}
} else if (parent instanceof BinaryExpression) {
final BinaryExpression binary = (BinaryExpression) parent;
final IElementType operator = binary.getOperationType();
final boolean isTargetOperator = OpenapiTypesUtil.tsCOMPARE_EQUALITY_OPS.contains(operator) || PhpTokenTypes.tsCOMPARE_ORDER_OPS.contains(operator);
if (isTargetOperator) {
final PsiElement second = OpenapiElementsUtil.getSecondOperand(binary, reference);
if (OpenapiTypesUtil.isNumber(second)) {
result = parent;
}
}
}
return result;
}
Aggregations