use of com.jetbrains.php.lang.psi.elements.ConstantReference 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.ConstantReference in project idea-php-typo3-plugin by cedricziel.
the class ConstantMatcherInspection method buildVisitor.
@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder problemsHolder, boolean b) {
return new PhpElementVisitor() {
@Override
public void visitPhpElement(PhpPsiElement element) {
if (!PlatformPatterns.psiElement(PhpElementTypes.CONSTANT_REF).accepts(element)) {
return;
}
ConstantReference constantReference = (ConstantReference) element;
Set<String> constants = getRemovedConstantsFQNs(constantReference);
if (constants.contains(constantReference.getFQN())) {
problemsHolder.registerProblem(element, "Constant removed with TYPO3 9, consider using an alternative");
}
}
};
}
use of com.jetbrains.php.lang.psi.elements.ConstantReference in project phpinspectionsea by kalessil.
the class ComparisonOperandsOrderInspector method buildVisitor.
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder problemsHolder, final boolean isOnTheFly) {
return new BasePhpElementVisitor() {
@Override
public void visitPhpBinaryExpression(@NotNull BinaryExpression expression) {
final IElementType operator = expression.getOperationType();
if (operator != null && OpenapiTypesUtil.tsCOMPARE_EQUALITY_OPS.contains(operator)) {
final PsiElement left = expression.getLeftOperand();
final PsiElement right = expression.getRightOperand();
if (left != null && right != null) {
final boolean isLeftConstant = left instanceof StringLiteralExpression || left instanceof ConstantReference || OpenapiTypesUtil.isNumber(left);
final boolean isRightConstant = right instanceof StringLiteralExpression || right instanceof ConstantReference || OpenapiTypesUtil.isNumber(right);
if (isLeftConstant != isRightConstant) {
final boolean isRegular = ComparisonStyle.isRegular();
if (isRightConstant && !isRegular) {
problemsHolder.registerProblem(expression, MessagesPresentationUtil.prefixWithEa(messageUseYoda), new TheLocalFix());
}
if (isLeftConstant && isRegular) {
problemsHolder.registerProblem(expression, MessagesPresentationUtil.prefixWithEa(messageUseRegular), new TheLocalFix());
}
}
}
}
}
};
}
use of com.jetbrains.php.lang.psi.elements.ConstantReference in project phpinspectionsea by kalessil.
the class AssertConstantStrategy method apply.
public static boolean apply(@NotNull String methodName, @NotNull MethodReference reference, @NotNull ProblemsHolder holder) {
boolean result = false;
if (targetMapping.containsKey(methodName)) {
final PsiElement[] arguments = reference.getParameters();
if (arguments.length > 1) {
for (final PsiElement argument : arguments) {
if (argument instanceof ConstantReference) {
final String constantName = ((ConstantReference) argument).getName();
if (constantName != null) {
final String constantNameNormalized = constantName.toLowerCase();
if (targetConstants.contains(constantNameNormalized)) {
final String suggestedAssertion = String.format(targetMapping.get(methodName), StringUtils.capitalize(constantNameNormalized));
final String[] suggestedArguments = new String[arguments.length - 1];
suggestedArguments[0] = Arrays.stream(arguments).filter(a -> a != argument).findFirst().get().getText();
if (arguments.length > 2) {
suggestedArguments[1] = arguments[2].getText();
}
holder.registerProblem(reference, String.format(MessagesPresentationUtil.prefixWithEa(messagePattern), suggestedAssertion), new PhpUnitAssertFixer(suggestedAssertion, suggestedArguments));
result = true;
break;
}
}
}
}
}
}
return result;
}
use of com.jetbrains.php.lang.psi.elements.ConstantReference in project phpinspectionsea by kalessil.
the class JsonEncodingApiUsageInspector 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) {
if (functionName.equals("json_decode") && this.isFromRootNamespace(reference)) {
final PsiElement[] arguments = reference.getParameters();
if (HARDEN_DECODING_RESULT_TYPE && arguments.length == 1) {
final String replacement = String.format("%sjson_decode(%s, %s)", reference.getImmediateNamespaceName(), arguments[0].getText(), DECODE_AS_ARRAY ? "true" : "false");
holder.registerProblem(reference, MessagesPresentationUtil.prefixWithEa(messageResultType), DECODE_AS_ARRAY ? new DecodeIntoArrayFix(replacement) : new DecodeIntoObjectFix(replacement));
}
if (HARDEN_ERRORS_HANDLING && arguments.length > 0 && PhpLanguageLevel.get(holder.getProject()).atLeast(PhpLanguageLevel.PHP730)) {
final boolean hasFlag = arguments.length >= 4 && this.hasStricterHandlingFlags(arguments[3]);
if (!hasFlag) {
final String replacement = String.format("%sjson_decode(%s, %s, %s, %s)", reference.getImmediateNamespaceName(), arguments[0].getText(), arguments.length > 1 ? arguments[1].getText() : (HARDEN_DECODING_RESULT_TYPE && DECODE_AS_ARRAY ? "true" : "false"), arguments.length > 2 ? arguments[2].getText() : "512", arguments.length > 3 ? "JSON_THROW_ON_ERROR | " + arguments[3].getText() : "JSON_THROW_ON_ERROR");
holder.registerProblem(reference, MessagesPresentationUtil.prefixWithEa(messageErrorsHandling), new HardenErrorsHandlingFix(replacement));
}
}
} else if (functionName.equals("json_encode") && this.isFromRootNamespace(reference)) {
if (HARDEN_ERRORS_HANDLING && PhpLanguageLevel.get(holder.getProject()).atLeast(PhpLanguageLevel.PHP730)) {
final PsiElement[] arguments = reference.getParameters();
final boolean hasFlag = arguments.length >= 2 && this.hasStricterHandlingFlags(arguments[1]);
if (!hasFlag && arguments.length > 0) {
final String replacement;
if (arguments.length > 2) {
replacement = String.format("%sjson_encode(%s, %s, %s)", reference.getImmediateNamespaceName(), arguments[0].getText(), "JSON_THROW_ON_ERROR | " + arguments[1].getText(), arguments[2].getText());
} else {
replacement = String.format("%sjson_encode(%s, %s)", reference.getImmediateNamespaceName(), arguments[0].getText(), arguments.length > 1 ? "JSON_THROW_ON_ERROR | " + arguments[1].getText() : "JSON_THROW_ON_ERROR");
}
holder.registerProblem(reference, MessagesPresentationUtil.prefixWithEa(messageErrorsHandling), new HardenErrorsHandlingFix(replacement));
}
}
}
}
}
private boolean hasStricterHandlingFlags(@NotNull PsiElement argument) {
boolean hasFlag = false;
final Set<PsiElement> options = argument instanceof ConstantReference ? new HashSet<>(Collections.singletonList(argument)) : PossibleValuesDiscoveryUtil.discover(argument);
if (options.size() == 1) {
final PsiElement option = options.iterator().next();
if (OpenapiTypesUtil.isNumber(option)) {
/* properly resolved value */
hasFlag = strictHandlingFlags.containsValue(option.getText());
} else if (option instanceof ConstantReference) {
/* constant value resolution fails for some reason */
hasFlag = strictHandlingFlags.containsKey(((ConstantReference) option).getName());
} else {
/* a complex case like local variable or implicit flags combination */
hasFlag = PsiTreeUtil.findChildrenOfType(option, ConstantReference.class).stream().anyMatch(r -> strictHandlingFlags.containsKey(r.getName()));
}
}
options.clear();
return hasFlag;
}
};
}
Aggregations