use of com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor in project phpinspectionsea by kalessil.
the class AmbiguousMethodsCallsInArrayMappingInspector method buildVisitor.
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new BasePhpElementVisitor() {
@Override
public void visitPhpFor(@NotNull For loop) {
final GroupStatement body = ExpressionSemanticUtil.getGroupStatement(loop);
if (body != null) {
this.analyzeBody(body);
}
}
@Override
public void visitPhpForeach(@NotNull ForeachStatement loop) {
final GroupStatement body = ExpressionSemanticUtil.getGroupStatement(loop);
if (body != null) {
this.analyzeBody(body);
}
}
private void analyzeBody(@NotNull GroupStatement body) {
for (final PsiElement instruction : body.getStatements()) {
final PsiElement candidate = instruction.getFirstChild();
if (candidate instanceof AssignmentExpression) {
final AssignmentExpression assignment = (AssignmentExpression) candidate;
final PsiElement value = assignment.getValue();
final PsiElement container = assignment.getVariable();
if (value != null && container instanceof ArrayAccessExpression) {
this.analyzeStatement((ArrayAccessExpression) container, value);
}
}
}
}
private void analyzeStatement(@NotNull ArrayAccessExpression container, @NotNull PsiElement value) {
final Collection<FunctionReference> left = PsiTreeUtil.findChildrenOfType(container, FunctionReference.class);
if (!left.isEmpty()) {
final Collection<FunctionReference> right = PsiTreeUtil.findChildrenOfType(value, FunctionReference.class);
if (value instanceof FunctionReference) {
right.add((FunctionReference) value);
}
if (!right.isEmpty()) {
iterate: for (final FunctionReference current : right) {
final String currentName = current.getName();
for (final FunctionReference candidate : left) {
final String candidateName = candidate.getName();
if (currentName != null && currentName.equals(candidateName) && OpenapiEquivalenceUtil.areEqual(current, candidate)) {
holder.registerProblem(current, MessagesPresentationUtil.prefixWithEa(message));
break iterate;
}
}
}
right.clear();
}
left.clear();
}
}
};
}
use of com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor 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.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor in project phpinspectionsea by kalessil.
the class ParameterDefaultValueIsNotNullInspector method buildVisitor.
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new BasePhpElementVisitor() {
@Override
public void visitPhpMethod(@NotNull Method method) {
this.analyze(method);
}
@Override
public void visitPhpFunction(@NotNull Function function) {
this.analyze(function);
}
private void analyze(@NotNull Function function) {
final Parameter[] arguments = function.getParameters();
if (arguments.length > 0) {
/* collect violations */
final List<Parameter> violations = new ArrayList<>();
for (final Parameter argument : arguments) {
final PsiElement defaultValue = argument.getDefaultValue();
if (defaultValue != null && !PhpLanguageUtil.isNull(defaultValue)) {
/* false-positives: null can not be used due to implicit type hints */
final PhpType declared = OpenapiResolveUtil.resolveDeclaredType(argument);
if (declared.isEmpty() || declared.getTypes().stream().anyMatch(t -> Types.getType(t).equals(Types.strNull))) {
violations.add(argument);
}
}
}
if (!violations.isEmpty()) {
/* false-positives: methods overrides, so violation should be addressed in the parent */
if (function instanceof Method) {
final PhpClass clazz = ((Method) function).getContainingClass();
if (clazz != null) {
final PhpClass parent = OpenapiResolveUtil.resolveSuperClass(clazz);
if (parent != null) {
final Method parentMethod = OpenapiResolveUtil.resolveMethod(parent, function.getName());
if (parentMethod != null && !parentMethod.getAccess().isPrivate()) {
violations.clear();
return;
}
}
}
}
/* report violations */
violations.forEach(param -> holder.registerProblem(param, MessagesPresentationUtil.prefixWithEa(message)));
violations.clear();
}
}
}
};
}
use of com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor in project phpinspectionsea by kalessil.
the class EfferentObjectCouplingInspector method buildVisitor.
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly) {
return new BasePhpElementVisitor() {
@Override
public void visitPhpClass(@NotNull PhpClass clazz) {
final PsiElement nameIdentifier = NamedElementUtil.getNameIdentifier(clazz);
if (nameIdentifier != null) {
final Set<String> references = PsiTreeUtil.findChildrenOfType(clazz, ClassReference.class).stream().map(ClassReference::getFQN).collect(Collectors.toSet());
final int count = references.size();
if (count >= optionCouplingLimit) {
holder.registerProblem(nameIdentifier, String.format(MessagesPresentationUtil.prefixWithEa(messagePattern), count));
}
}
}
};
}
use of com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor in project phpinspectionsea by kalessil.
the class MissUsingParentKeywordInspector method buildVisitor.
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new BasePhpElementVisitor() {
@Override
public void visitPhpMethodReference(@NotNull MethodReference reference) {
final PsiElement base = reference.getClassReference();
if (base instanceof ClassReference && base.getText().equals("parent")) {
final Function scope = ExpressionSemanticUtil.getScope(reference);
if (scope instanceof Method) {
final Method context = (Method) scope;
final PhpClass clazz = context.getContainingClass();
if (clazz != null && !clazz.isTrait() && !context.isStatic()) {
final String methodName = scope.getName();
final String referenceName = reference.getName();
if (referenceName != null && !referenceName.equals(methodName)) {
final boolean isTarget = clazz.findOwnMethodByName(referenceName) == null && !this.isOverridden(clazz, referenceName);
if (isTarget) {
final PsiElement resolved = OpenapiResolveUtil.resolveReference(reference);
if (resolved instanceof Method) {
final PsiElement parameters = reference.getParameterList();
final String replacement = String.format(((Method) resolved).isStatic() ? "self::%s(%s)" : "$this->%s(%s)", referenceName, parameters == null ? "" : parameters.getText());
holder.registerProblem(reference, String.format(MessagesPresentationUtil.prefixWithEa(messagePattern), replacement), new NormalizeClassReferenceFix(replacement));
}
}
}
}
}
}
}
final boolean isOverridden(@NotNull PhpClass clazz, @NotNull String methodName) {
if (!clazz.isFinal()) {
final PhpIndex index = PhpIndex.getInstance(holder.getProject());
final Collection<PhpClass> children = OpenapiResolveUtil.resolveChildClasses(clazz.getFQN(), index);
return children.stream().anyMatch(c -> c.findOwnMethodByName(methodName) != null);
}
return false;
}
};
}
Aggregations