use of com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor in project phpinspectionsea by kalessil.
the class IncorrectRandomRangeInspector 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 && functions.contains(functionName)) {
final PsiElement[] arguments = reference.getParameters();
if (arguments.length == 2) {
final Set<PsiElement> fromVariants = PossibleValuesDiscoveryUtil.discover(arguments[0]);
if (fromVariants.size() == 1) {
final PsiElement from = fromVariants.iterator().next();
if (OpenapiTypesUtil.isNumber(from)) {
final Set<PsiElement> toVariants = PossibleValuesDiscoveryUtil.discover(arguments[1]);
if (toVariants.size() == 1) {
final PsiElement to = toVariants.iterator().next();
if (OpenapiTypesUtil.isNumber(to)) {
boolean isTarget;
try {
isTarget = Long.parseLong(to.getText()) < Long.parseLong(from.getText());
} catch (final NumberFormatException wrongFormat) {
isTarget = false;
}
if (isTarget) {
holder.registerProblem(reference, MessagesPresentationUtil.prefixWithEa(message));
}
}
}
toVariants.clear();
}
}
fromVariants.clear();
}
}
}
};
}
use of com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor in project phpinspectionsea by kalessil.
the class OffsetOperationsInspector method buildVisitor.
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new BasePhpElementVisitor() {
@Override
public void visitPhpArrayAccessExpression(@NotNull ArrayAccessExpression expression) {
final PsiElement bracketNode = expression.getLastChild();
if (null == bracketNode || null == expression.getValue()) {
return;
}
// ensure offsets operations are supported, do nothing if no types were resolved
final Set<String> allowedIndexTypes = new HashSet<>();
if (!isContainerSupportsArrayAccess(holder.getProject(), expression, allowedIndexTypes) && !allowedIndexTypes.isEmpty()) {
holder.registerProblem(expression, String.format(MessagesPresentationUtil.prefixWithEa(patternNoOffsetSupport), expression.getValue().getText(), allowedIndexTypes.toString()));
allowedIndexTypes.clear();
return;
}
// TODO: hash-elements e.g. array initialization
if (!allowedIndexTypes.isEmpty() && expression.getIndex() != null) {
final PhpPsiElement indexValue = expression.getIndex().getValue();
if (indexValue instanceof PhpTypedElement) {
final PhpType resolved = OpenapiResolveUtil.resolveType((PhpTypedElement) indexValue, holder.getProject());
if (resolved != null) {
final Set<String> indexTypes = new HashSet<>();
resolved.filterUnknown().getTypes().forEach(t -> indexTypes.add(Types.getType(t)));
if (!indexTypes.isEmpty()) {
filterPossibleTypesWhichAreNotAllowed(indexTypes, allowedIndexTypes);
if (!indexTypes.isEmpty()) {
holder.registerProblem(indexValue, String.format(MessagesPresentationUtil.prefixWithEa(patternInvalidIndex), indexTypes.toString(), allowedIndexTypes.toString()));
indexTypes.clear();
}
}
}
}
}
// clear valid types collection
allowedIndexTypes.clear();
}
};
}
use of com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor in project phpinspectionsea by kalessil.
the class IncrementDecrementOperationEquivalentInspector method buildVisitor.
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new BasePhpElementVisitor() {
/* ensures we are not touching arrays only, not strings and not objects */
private boolean isArrayAccessOrString(@Nullable PhpPsiElement variable) {
if (variable instanceof ArrayAccessExpression) {
final PsiElement container = ((ArrayAccessExpression) variable).getValue();
if (container instanceof PhpTypedElement) {
final PhpType resolved = OpenapiResolveUtil.resolveType((PhpTypedElement) container, holder.getProject());
if (resolved != null) {
final Set<String> types = new HashSet<>();
resolved.filterUnknown().getTypes().forEach(t -> types.add(Types.getType(t)));
final boolean isArray = types.contains(Types.strArray) && !types.contains(Types.strString);
types.clear();
return !isArray;
}
}
}
return false;
}
@Override
public void visitPhpSelfAssignmentExpression(@NotNull SelfAssignmentExpression expression) {
final IElementType operation = expression.getOperationType();
final PhpPsiElement value = expression.getValue();
final PhpPsiElement variable = expression.getVariable();
if (null != value && null != operation && null != variable) {
if (operation == PhpTokenTypes.opPLUS_ASGN) {
if (value.getText().equals("1") && !isArrayAccessOrString(variable)) {
final String replacement = PREFER_PREFIX_STYLE ? ("++" + variable.getText()) : (variable.getText() + "++");
holder.registerProblem(expression, MessagesPresentationUtil.prefixWithEa(patternMessage.replace("%e%", replacement)), new UseIncrementFix(replacement));
}
} else if (operation == PhpTokenTypes.opMINUS_ASGN) {
if (value.getText().equals("1") && !isArrayAccessOrString(variable)) {
final String replacement = PREFER_PREFIX_STYLE ? ("--" + variable.getText()) : (variable.getText() + "--");
holder.registerProblem(expression, MessagesPresentationUtil.prefixWithEa(patternMessage.replace("%e%", replacement)), new UseDecrementFix(replacement));
}
}
}
}
@Override
public void visitPhpAssignmentExpression(@NotNull AssignmentExpression assignmentExpression) {
final PhpPsiElement variable = assignmentExpression.getVariable();
if (variable != null && assignmentExpression.getValue() instanceof BinaryExpression) {
final BinaryExpression value = (BinaryExpression) assignmentExpression.getValue();
/* operation and operands provided */
final PsiElement leftOperand = value.getLeftOperand();
final PsiElement rightOperand = value.getRightOperand();
final IElementType operation = value.getOperationType();
if (null == leftOperand || null == rightOperand || null == operation) {
return;
}
if (operation == PhpTokenTypes.opPLUS) {
/* plus operation: operand position NOT important */
if ((leftOperand.getText().equals("1") && OpenapiEquivalenceUtil.areEqual(rightOperand, variable)) || (rightOperand.getText().equals("1") && OpenapiEquivalenceUtil.areEqual(leftOperand, variable))) {
if (!isArrayAccessOrString(variable)) {
final String replacement = PREFER_PREFIX_STYLE ? ("++" + variable.getText()) : (variable.getText() + "++");
holder.registerProblem(assignmentExpression, MessagesPresentationUtil.prefixWithEa(patternMessage.replace("%e%", replacement)), new UseIncrementFix(replacement));
}
}
} else if (operation == PhpTokenTypes.opMINUS) {
/* minus operation: operand position IS important */
if (rightOperand.getText().equals("1") && OpenapiEquivalenceUtil.areEqual(leftOperand, variable) && !isArrayAccessOrString(variable)) {
final String replacement = PREFER_PREFIX_STYLE ? ("--" + variable.getText()) : (variable.getText() + "--");
holder.registerProblem(assignmentExpression, MessagesPresentationUtil.prefixWithEa(patternMessage.replace("%e%", replacement)), new UseDecrementFix(replacement));
}
}
}
}
};
}
use of com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor in project phpinspectionsea by kalessil.
the class AutoloadingIssuesInspector method buildVisitor.
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new BasePhpElementVisitor() {
@Override
public void visitPhpFile(@NotNull PhpFile file) {
final String fileName = file.getName();
if (fileName.endsWith(".php") && !ignoredFiles.contains(fileName) && !laravelMigration.matcher(fileName).matches()) {
final List<PhpClass> classes = new ArrayList<>();
file.getTopLevelDefs().values().stream().filter(definition -> definition instanceof PhpClass).forEach(definition -> classes.add((PhpClass) definition));
if (classes.size() == 1) {
final PhpClass clazz = classes.get(0);
final String className = clazz.getName();
/* PSR-0 classloading (Package_Subpackage_Class) naming */
String extractedClassName = className;
if (clazz.getFQN().lastIndexOf('\\') == 0 && extractedClassName.indexOf('_') != -1) {
extractedClassName = extractedClassName.substring(1 + extractedClassName.lastIndexOf('_'));
}
/* check the file name as per extraction compliant with PSR-0/PSR-4 standards */
final String expectedClassName = fileName.substring(0, fileName.indexOf('.'));
if (this.isBreakingPsrStandard(className, expectedClassName, extractedClassName) && !this.isWordpressStandard(className, fileName)) {
final PsiElement classNameNode = NamedElementUtil.getNameIdentifier(clazz);
if (classNameNode != null) {
holder.registerProblem(classNameNode, MessagesPresentationUtil.prefixWithEa(message));
}
}
}
classes.clear();
}
}
private boolean isBreakingPsrStandard(@NotNull String className, @NotNull String expectedClassName, @NotNull String extractedClassName) {
return !expectedClassName.equals(extractedClassName) && !expectedClassName.equals(className);
}
private boolean isWordpressStandard(@NotNull String className, @NotNull String fileName) {
final String wordpressFileName = String.format("class-%s.php", className.toLowerCase().replaceAll("_", "-"));
return fileName.endsWith(wordpressFileName);
}
};
}
use of com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor in project phpinspectionsea by kalessil.
the class ClassMethodNameMatchesFieldNameInspector method buildVisitor.
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new BasePhpElementVisitor() {
@Override
public void visitPhpMethod(@NotNull Method method) {
final PhpClass clazz = method.getContainingClass();
if (clazz != null && !clazz.isInterface()) {
final Field field = OpenapiResolveUtil.resolveField(clazz, method.getName());
if (field != null) {
final PsiElement nameNode = NamedElementUtil.getNameIdentifier(method);
final PhpType resolvedType = OpenapiResolveUtil.resolveType(field, holder.getProject());
if (resolvedType != null && nameNode != null) {
final PhpType knownType = resolvedType.filterUnknown();
if (knownType.isEmpty()) {
holder.registerProblem(nameNode, MessagesPresentationUtil.prefixWithEa(messageFieldType));
} else {
final boolean isCallable = knownType.getTypes().stream().anyMatch(t -> Types.getType(t).equals(Types.strCallable));
if (isCallable) {
holder.registerProblem(nameNode, MessagesPresentationUtil.prefixWithEa(messageMatches));
}
}
}
}
}
}
};
}
Aggregations