use of com.jetbrains.php.lang.psi.elements.UnaryExpression in project phpinspectionsea by kalessil.
the class FileFunctionMissUseInspector 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("file")) {
return;
}
final PsiElement[] arguments = reference.getParameters();
if (arguments.length != 1) {
return;
}
/* function can be silenced, get parent for this case; validate parent structure */
PsiElement parent = reference.getParent();
if (parent instanceof UnaryExpression) {
final PsiElement operation = ((UnaryExpression) parent).getOperation();
if (OpenapiTypesUtil.is(operation, PhpTokenTypes.opSILENCE)) {
parent = parent.getParent();
}
}
if (!(parent instanceof ParameterList) || !OpenapiTypesUtil.isFunctionReference(parent.getParent())) {
return;
}
/* validate parent functions' name (implode or join) and amount of arguments */
final FunctionReference parentReference = (FunctionReference) parent.getParent();
final String parentName = parentReference.getName();
if (parentName == null || (!parentName.equals("implode") && !parentName.equals("join"))) {
return;
}
final PsiElement[] parentParams = parentReference.getParameters();
if (parentParams.length != 2) {
return;
}
/* validate if glue is not empty */
final StringLiteralExpression glue = ExpressionSemanticUtil.resolveAsStringLiteral(parentParams[0]);
if (glue != null && !glue.getContents().isEmpty()) {
return;
}
final String message = String.format(messagePattern, arguments[0].getText());
holder.registerProblem(parentReference, message, ProblemHighlightType.GENERIC_ERROR, new TheLocalFix());
}
};
}
use of com.jetbrains.php.lang.psi.elements.UnaryExpression in project phpinspectionsea by kalessil.
the class IssetAndNullComparisonStrategy method apply.
public static boolean apply(@NotNull List<PsiElement> conditions, @NotNull ProblemsHolder holder) {
/* first ensure that we have null identity checks at all */
final Map<PsiElement, PsiElement> nullTestSubjects = new HashMap<>();
for (final PsiElement oneCondition : conditions) {
if (oneCondition instanceof BinaryExpression) {
final BinaryExpression expression = (BinaryExpression) oneCondition;
/* we need only !== and === operations */
final IElementType operator = expression.getOperationType();
if (operator != PhpTokenTypes.opIDENTICAL && operator != PhpTokenTypes.opNOT_IDENTICAL) {
continue;
}
/* quickly check if any operands is a constant */
final PsiElement left = expression.getLeftOperand();
final PsiElement right = expression.getRightOperand();
if (!(left instanceof ConstantReference) && !(right instanceof ConstantReference)) {
continue;
}
/* store null test subjects */
if (PhpLanguageUtil.isNull(right)) {
if (null != left) {
nullTestSubjects.put(expression, left);
}
continue;
}
if (PhpLanguageUtil.isNull(left)) {
if (null != right) {
nullTestSubjects.put(expression, right);
}
// continue;
}
}
}
if (0 == nullTestSubjects.size()) {
return false;
}
boolean hasReportedExpressions = false;
for (final PsiElement oneCondition : conditions) {
/* do not process null identity checks */
if (nullTestSubjects.containsKey(oneCondition)) {
continue;
}
/* unwrap ! and () */
PsiElement issetCandidate = oneCondition;
if (issetCandidate instanceof UnaryExpression) {
final PsiElement notOperatorCandidate = ((UnaryExpression) issetCandidate).getOperation();
if (null != notOperatorCandidate && notOperatorCandidate.getNode().getElementType() == PhpTokenTypes.opNOT) {
PsiElement invertedValue = ((UnaryExpression) issetCandidate).getValue();
invertedValue = ExpressionSemanticUtil.getExpressionTroughParenthesis(invertedValue);
if (null == invertedValue) {
continue;
}
issetCandidate = invertedValue;
}
}
if (!(issetCandidate instanceof PhpIsset) || 0 == ((PhpIsset) issetCandidate).getVariables().length) {
continue;
}
/* process isset constructions */
for (final PsiElement issetArgument : ((PhpIsset) issetCandidate).getVariables()) {
/* compare with know null identity checked subjects */
for (final Map.Entry<PsiElement, PsiElement> nullTestPair : nullTestSubjects.entrySet()) {
if (!OpeanapiEquivalenceUtil.areEqual(nullTestPair.getValue(), issetArgument)) {
continue;
}
hasReportedExpressions = true;
final PsiElement nullTestExpression = nullTestPair.getKey();
final String message = messagePattern.replace("%e%", nullTestExpression.getText());
holder.registerProblem(nullTestExpression, message, ProblemHighlightType.WEAK_WARNING);
}
}
}
nullTestSubjects.clear();
return hasReportedExpressions;
}
use of com.jetbrains.php.lang.psi.elements.UnaryExpression in project phpinspectionsea by kalessil.
the class StrEndsWithCanBeUsedInspector 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("substr") || functionName.equals("mb_substr"))) {
final boolean isTargetVersion = PhpLanguageLevel.get(holder.getProject()).atLeast(PhpLanguageLevel.PHP800);
if (isTargetVersion) {
final PsiElement[] arguments = reference.getParameters();
if (arguments.length == 2) {
final PsiElement context = reference.getParent();
if (context instanceof BinaryExpression) {
final BinaryExpression binary = (BinaryExpression) context;
final IElementType operation = binary.getOperationType();
if (operation == PhpTokenTypes.opNOT_IDENTICAL || operation == PhpTokenTypes.opIDENTICAL) {
final PsiElement limitArgument = this.extractLimitArgument(arguments[1]);
final PsiElement second = OpenapiElementsUtil.getSecondOperand(binary, reference);
if (second != null && limitArgument != null && OpenapiEquivalenceUtil.areEqual(second, limitArgument)) {
final String replacement = String.format("%s%sstr_ends_with(%s, %s)", operation == PhpTokenTypes.opNOT_IDENTICAL ? "! " : "", reference.getImmediateNamespaceName(), arguments[0].getText(), second.getText());
holder.registerProblem(binary, String.format(MessagesPresentationUtil.prefixWithEa(message), replacement), new UseStrEndsWithFix(replacement));
}
}
}
}
}
}
}
@Nullable
private PsiElement extractLimitArgument(@Nullable PsiElement expression) {
if (expression instanceof UnaryExpression) {
final UnaryExpression unary = (UnaryExpression) expression;
if (OpenapiTypesUtil.is(unary.getOperation(), PhpTokenTypes.opMINUS)) {
final PsiElement argument = unary.getValue();
if (OpenapiTypesUtil.isFunctionReference(argument)) {
final FunctionReference reference = (FunctionReference) argument;
final String functionName = reference.getName();
if (functionName != null && (functionName.equals("strlen") || functionName.equals("mb_strlen"))) {
final PsiElement[] arguments = reference.getParameters();
if (arguments.length == 1) {
return arguments[0];
}
}
}
}
}
return null;
}
};
}
use of com.jetbrains.php.lang.psi.elements.UnaryExpression in project phpinspectionsea by kalessil.
the class StrStrUsedAsStrPosInspector 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 && mapping.containsKey(functionName)) {
final PsiElement[] arguments = reference.getParameters();
if (arguments.length >= 2) {
/* checks implicit boolean comparison pattern */
final PsiElement parent = reference.getParent();
if (parent instanceof BinaryExpression) {
final BinaryExpression binary = (BinaryExpression) parent;
if (OpenapiTypesUtil.tsCOMPARE_EQUALITY_OPS.contains(binary.getOperationType())) {
final PsiElement secondOperand = OpenapiElementsUtil.getSecondOperand(binary, reference);
if (PhpLanguageUtil.isFalse(secondOperand)) {
final PsiElement operationNode = binary.getOperation();
if (operationNode != null) {
String operation = operationNode.getText();
operation = operation.length() == 2 ? operation + '=' : operation;
final String call = String.format("%s%s(%s, %s)", reference.getImmediateNamespaceName(), mapping.get(functionName), arguments[0].getText(), arguments[1].getText());
final boolean isRegular = ComparisonStyle.isRegular();
final String replacement = String.format("%s %s %s", isRegular ? call : "false", operation, isRegular ? "false" : call);
holder.registerProblem(binary, String.format(MessagesPresentationUtil.prefixWithEa(messagePattern), replacement), new UseStrposFix(replacement));
return;
}
}
}
}
/* checks non-implicit boolean comparison patternS */
if (ExpressionSemanticUtil.isUsedAsLogicalOperand(reference)) {
final String operation = parent instanceof UnaryExpression ? "===" : "!==";
final String call = String.format("%s%s(%s, %s)", reference.getImmediateNamespaceName(), mapping.get(functionName), arguments[0].getText(), arguments[1].getText());
final boolean isRegular = ComparisonStyle.isRegular();
final String replacement = String.format("%s %s %s", isRegular ? call : "false", operation, isRegular ? "false" : call);
holder.registerProblem(parent instanceof UnaryExpression ? parent : reference, String.format(MessagesPresentationUtil.prefixWithEa(messagePattern), replacement), new UseStrposFix(replacement));
}
}
}
}
};
}
use of com.jetbrains.php.lang.psi.elements.UnaryExpression 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;
}
Aggregations