use of com.jetbrains.php.lang.psi.elements.UnaryExpression in project phpinspectionsea by kalessil.
the class StrlenInEmptyStringCheckContextInspection method buildVisitor.
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new BasePhpElementVisitor() {
@Override
public void visitPhpFunctionCall(@NotNull FunctionReference reference) {
final String functionName = reference.getName();
if (functionName != null && (functionName.equals("strlen") || functionName.equals("mb_strlen"))) {
final PsiElement[] arguments = reference.getParameters();
if (arguments.length > 0 && ExpressionSemanticUtil.getBlockScope(reference) != null) {
boolean isMatchedPattern = false;
boolean isEmptyString = false;
PsiElement target = null;
/* check explicit numbers comparisons */
final PsiElement parent = reference.getParent();
if (parent instanceof BinaryExpression) {
final BinaryExpression binary = (BinaryExpression) parent;
final PsiElement left = binary.getLeftOperand();
final PsiElement secondOperand = OpenapiElementsUtil.getSecondOperand(binary, reference);
/* second operand should be a number */
if (OpenapiTypesUtil.isNumber(secondOperand)) {
final String number = secondOperand.getText();
/* check cases when comparing with 1 */
final IElementType operator = binary.getOperationType();
if (operator == PhpTokenTypes.opGREATER) {
isMatchedPattern = left == reference && number.equals("0");
target = binary;
isEmptyString = false;
} else if (operator == PhpTokenTypes.opLESS || operator == PhpTokenTypes.opGREATER_OR_EQUAL) {
isMatchedPattern = left == reference && number.equals("1");
target = binary;
isEmptyString = operator == PhpTokenTypes.opLESS;
}
/* check cases when checking equality to 0 */
if (!isMatchedPattern && OpenapiTypesUtil.tsCOMPARE_EQUALITY_OPS.contains(operator)) {
isMatchedPattern = number.equals("0");
target = binary;
isEmptyString = operator == PhpTokenTypes.opIDENTICAL || operator == PhpTokenTypes.opEQUAL;
}
}
}
/* checks NON-implicit boolean comparison patterns */
if (!isMatchedPattern && ExpressionSemanticUtil.isUsedAsLogicalOperand(reference)) {
isMatchedPattern = true;
target = reference;
final PsiElement operation = parent instanceof UnaryExpression ? ((UnaryExpression) parent).getOperation() : null;
if (operation != null) {
isEmptyString = OpenapiTypesUtil.is(operation, PhpTokenTypes.opNOT);
target = parent;
}
}
/* investigate possible issues */
if (isMatchedPattern) {
final boolean isRegular = ComparisonStyle.isRegular();
final String operator = (isEmptyString ? "=" : "!") + (this.canApplyIdentityOperator(arguments[0]) ? "==" : "=");
final String replacement = String.format(isRegular ? "%s %s ''" : "'' %s %s", isRegular ? arguments[0].getText() : operator, isRegular ? operator : arguments[0].getText());
holder.registerProblem(target, String.format(MessagesPresentationUtil.prefixWithEa(messagePattern), replacement), new CompareToEmptyStringFix(replacement));
}
}
}
}
private boolean canApplyIdentityOperator(@NotNull PsiElement value) {
if (value instanceof PhpTypedElement) {
final PhpType resolved = OpenapiResolveUtil.resolveType((PhpTypedElement) value, holder.getProject());
if (resolved != null && resolved.size() == 1) {
return Types.strString.equals(Types.getType(resolved.getTypes().iterator().next()));
}
}
return false;
}
};
}
use of com.jetbrains.php.lang.psi.elements.UnaryExpression in project phpinspectionsea by kalessil.
the class UnclearOperationsPriorityStrategy method apply.
public static boolean apply(@NotNull BinaryExpression expression, @NotNull ProblemsHolder holder) {
final IElementType operator = expression.getOperationType();
final PsiElement parent = expression.getParent();
if (operator == PhpTokenTypes.opAND || operator == PhpTokenTypes.opOR) {
/* binary expressions, already wrapped into parentheses can be skipped */
if (parent instanceof BinaryExpression) {
final IElementType parentOperator = ((BinaryExpression) parent).getOperationType();
if (parentOperator != operator && (parentOperator == PhpTokenTypes.opAND || parentOperator == PhpTokenTypes.opOR)) {
final String replacement = '(' + expression.getText() + ')';
holder.registerProblem(expression, MessagesPresentationUtil.prefixWithEa(message), new WrapItAsItIsFix(replacement));
return true;
}
} else /* assignment dramatically changing precedence */
if (OpenapiTypesUtil.isAssignment(parent) && !OpenapiTypesUtil.isStatementImpl(parent.getParent())) {
final String replacement = '(' + expression.getText() + ')';
holder.registerProblem(expression, MessagesPresentationUtil.prefixWithEa(message), new WrapItAsItIsFix(replacement));
return true;
}
} else if (PhpTokenTypes.tsCOMPARE_OPS.contains(operator)) {
if (OpenapiTypesUtil.isAssignment(parent) && parent.getParent() instanceof If) {
final AssignmentExpression assignment = (AssignmentExpression) parent;
final PsiElement assignedValue = assignment.getValue();
if (assignedValue != null) {
final String value = assignedValue.getText();
final String replacement = assignment.getText().replace(value, '(' + value + ')');
holder.registerProblem(parent, MessagesPresentationUtil.prefixWithEa(message), new WrapItAsItIsFix(replacement));
return true;
}
} else if (PhpTokenTypes.tsCOMPARE_ORDER_OPS.contains(operator) && operator != PhpTokenTypes.opSPACESHIP) {
final PsiElement left = expression.getLeftOperand();
if (left instanceof UnaryExpression) {
final UnaryExpression candidate = (UnaryExpression) left;
if (OpenapiTypesUtil.is(candidate.getOperation(), PhpTokenTypes.opNOT)) {
final String value = candidate.getText();
final String replacement = expression.getText().replace(value, '(' + value + ')');
holder.registerProblem(expression, MessagesPresentationUtil.prefixWithEa(message), new WrapItAsItIsFix(replacement));
return true;
}
}
}
}
return false;
}
use of com.jetbrains.php.lang.psi.elements.UnaryExpression in project phpinspectionsea by kalessil.
the class AssertBoolInvertedStrategy 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("assertFalse"))) {
final PsiElement param = ExpressionSemanticUtil.getExpressionTroughParenthesis(params[0]);
if (param instanceof UnaryExpression) {
final UnaryExpression not = (UnaryExpression) param;
if (!OpenapiTypesUtil.is(not.getOperation(), PhpTokenTypes.opNOT)) {
return false;
}
final PsiElement invertedParam = ExpressionSemanticUtil.getExpressionTroughParenthesis(not.getValue());
if (null == invertedParam) {
return false;
}
final String replacementMethod = function.equals("assertTrue") ? "assertNotTrue" : "assertNotFalse";
holder.registerProblem(reference, String.format(MessagesPresentationUtil.prefixWithEa(messagePattern), replacementMethod), new TheLocalFix(holder.getProject(), replacementMethod, invertedParam));
return true;
}
}
return false;
}
use of com.jetbrains.php.lang.psi.elements.UnaryExpression in project phpinspectionsea by kalessil.
the class GenerateAlternativeFromIssetStrategy method generate.
@Nullable
public static String generate(@NotNull TernaryExpression expression) {
/* handle inverted cases */
PsiElement issetCandidate = ExpressionSemanticUtil.getExpressionTroughParenthesis(expression.getCondition());
boolean isInverted = false;
if (issetCandidate instanceof UnaryExpression) {
final PsiElement operator = ((UnaryExpression) issetCandidate).getOperation();
if (null != operator && PhpTokenTypes.opNOT == operator.getNode().getElementType()) {
isInverted = true;
issetCandidate = ((UnaryExpression) issetCandidate).getValue();
}
}
/* verify condition structure */
final PhpIsset isset = issetCandidate instanceof PhpIsset ? (PhpIsset) issetCandidate : null;
if (null == isset || 1 != isset.getVariables().length) {
return null;
}
/* verify subject match and alternative availability */
final PsiElement subject = ExpressionSemanticUtil.getExpressionTroughParenthesis(isset.getVariables()[0]);
final PsiElement value = ExpressionSemanticUtil.getExpressionTroughParenthesis(isInverted ? expression.getFalseVariant() : expression.getTrueVariant());
final PsiElement alternative = ExpressionSemanticUtil.getExpressionTroughParenthesis(isInverted ? expression.getTrueVariant() : expression.getFalseVariant());
if (null == subject || null == value || null == alternative || !OpenapiEquivalenceUtil.areEqual(subject, value)) {
return null;
}
return subject.getText() + " ?? " + alternative.getText();
}
use of com.jetbrains.php.lang.psi.elements.UnaryExpression in project phpinspectionsea by kalessil.
the class GenerateAlternativeFromArrayKeyExistsStrategy method generate.
@Nullable
public static String generate(@NotNull TernaryExpression expression) {
/* handle inverted cases */
PsiElement callCandidate = ExpressionSemanticUtil.getExpressionTroughParenthesis(expression.getCondition());
boolean isInverted = false;
if (callCandidate instanceof UnaryExpression) {
final PsiElement operator = ((UnaryExpression) callCandidate).getOperation();
if (null != operator && PhpTokenTypes.opNOT == operator.getNode().getElementType()) {
isInverted = true;
callCandidate = ((UnaryExpression) callCandidate).getValue();
}
}
/* verify condition structure */
final FunctionReference call = OpenapiTypesUtil.isFunctionReference(callCandidate) ? (FunctionReference) callCandidate : null;
final String functionName = null == call ? null : call.getName();
if (null == functionName || 2 != call.getParameters().length || !functionName.equals("array_key_exists")) {
return null;
}
/* array_key_exists is valid only with null-alternatives */
final PsiElement alternative = ExpressionSemanticUtil.getExpressionTroughParenthesis(isInverted ? expression.getTrueVariant() : expression.getFalseVariant());
final PsiElement value = ExpressionSemanticUtil.getExpressionTroughParenthesis(isInverted ? expression.getFalseVariant() : expression.getTrueVariant());
if (!(value instanceof ArrayAccessExpression) || !PhpLanguageUtil.isNull(alternative)) {
return null;
}
/* verify condition and variant structure */
final PsiElement[] params = call.getParameters();
final ArrayAccessExpression array = (ArrayAccessExpression) value;
final PsiElement container = array.getValue();
final PsiElement index = null == array.getIndex() ? null : array.getIndex().getValue();
if (null == params[0] || null == params[1] || null == container || null == index) {
return null;
}
if (!OpenapiEquivalenceUtil.areEqual(params[1], container) || !OpenapiEquivalenceUtil.areEqual(params[0], index)) {
return null;
}
return value.getText() + " ?? " + alternative.getText();
}
Aggregations