use of com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor in project phpinspectionsea by kalessil.
the class StaticLambdaBindingInspector method buildVisitor.
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new BasePhpElementVisitor() {
@Override
public void visitPhpFunction(@NotNull Function function) {
final Project project = holder.getProject();
if (PhpLanguageLevel.get(project).atLeast(PhpLanguageLevel.PHP540) && OpenapiTypesUtil.isLambda(function)) {
final boolean isTarget = OpenapiTypesUtil.is(function.getFirstChild(), PhpTokenTypes.kwSTATIC);
if (isTarget) {
final GroupStatement body = ExpressionSemanticUtil.getGroupStatement(function);
if (body != null) {
for (final PsiElement element : PsiTreeUtil.findChildrenOfAnyType(body, Variable.class, MethodReference.class)) {
if (element instanceof Variable) {
final Variable variable = (Variable) element;
if (variable.getName().equals("this") && function == ExpressionSemanticUtil.getScope(variable)) {
holder.registerProblem(variable, MessagesPresentationUtil.prefixWithEa(messageThis), new TurnClosureIntoNonStaticFix(project, function.getFirstChild()));
return;
}
} else {
final MethodReference reference = (MethodReference) element;
final PsiElement base = reference.getFirstChild();
if (base instanceof ClassReference && base.getText().equals("parent")) {
final PsiElement resolved = OpenapiResolveUtil.resolveReference(reference);
if (resolved instanceof Method && !((Method) resolved).isStatic()) {
holder.registerProblem(reference, MessagesPresentationUtil.prefixWithEa(messageParent), new TurnClosureIntoNonStaticFix(project, function.getFirstChild()));
return;
}
}
}
}
}
}
}
}
};
}
use of com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor in project phpinspectionsea by kalessil.
the class UnsupportedEmptyListAssignmentsInspector method buildVisitor.
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new BasePhpElementVisitor() {
@Override
public void visitPhpForeach(@NotNull ForeachStatement expression) {
if (PhpLanguageLevel.get(holder.getProject()).atLeast(PhpLanguageLevel.PHP700) && expression.getVariables().isEmpty()) {
final PsiElement first = expression.getFirstChild();
if (first != null) {
boolean reachedAsKeyword = false;
boolean isTarget = false;
PsiElement current = first.getNextSibling();
while (current != null) {
if (!reachedAsKeyword) {
reachedAsKeyword = OpenapiTypesUtil.is(current, PhpTokenTypes.kwAS);
} else {
isTarget = OpenapiTypesUtil.is(current, PhpTokenTypes.kwLIST) || OpenapiTypesUtil.is(current, PhpTokenTypes.chLBRACKET);
if (isTarget) {
break;
}
}
current = current.getNextSibling();
}
if (isTarget) {
holder.registerProblem(current, MessagesPresentationUtil.prefixWithEa(message), ProblemHighlightType.GENERIC_ERROR);
}
}
}
}
};
}
use of com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor in project phpinspectionsea by kalessil.
the class IssetArgumentExistenceInspector method buildVisitor.
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new BasePhpElementVisitor() {
@Override
public void visitPhpBinaryExpression(@NotNull BinaryExpression expression) {
final PsiElement candidate = expression.getLeftOperand();
if (candidate instanceof Variable && PhpTokenTypes.opCOALESCE == expression.getOperationType()) {
final Variable variable = (Variable) candidate;
if (!this.getSuppliedVariables(expression).contains(variable.getName())) {
analyzeExistence(variable);
}
}
}
@Override
public void visitPhpEmpty(@NotNull PhpEmpty expression) {
this.analyzeArgumentsExistence(expression.getVariables());
}
@Override
public void visitPhpIsset(@NotNull PhpIsset expression) {
this.analyzeArgumentsExistence(expression.getVariables());
}
private void analyzeArgumentsExistence(@NotNull PhpExpression[] arguments) {
if (arguments.length > 0) {
final Set<String> parameters = this.getSuppliedVariables(arguments[0]);
for (final PhpExpression argument : arguments) {
if (argument instanceof Variable && !parameters.contains(argument.getName())) {
this.analyzeExistence((Variable) argument);
}
}
parameters.clear();
}
}
private void analyzeExistence(@NotNull Variable variable) {
final String variableName = variable.getName();
if (!variableName.isEmpty() && !specialVariables.contains(variableName)) {
final Function scope = ExpressionSemanticUtil.getScope(variable);
final GroupStatement body = scope == null ? null : ExpressionSemanticUtil.getGroupStatement(scope);
if (body != null) {
for (final Variable reference : PsiTreeUtil.findChildrenOfType(body, Variable.class)) {
if (reference.getName().equals(variableName)) {
boolean report = reference == variable;
if (!report) {
final PsiElement parent = reference.getParent();
if (parent instanceof AssignmentExpression) {
report = PsiTreeUtil.findCommonParent(reference, variable) == parent;
}
}
if (report) {
/* variable created dynamically in a loop: hacky stuff, but nevertheless */
PsiElement loopCandidate = reference.getParent();
while (loopCandidate != null && loopCandidate != scope) {
if (OpenapiTypesUtil.isLoop(loopCandidate)) {
report = PsiTreeUtil.findChildrenOfType(loopCandidate, AssignmentExpression.class).stream().noneMatch(assignment -> {
final PsiElement container = assignment.getVariable();
return container instanceof Variable && ((Variable) container).getName().equals(variableName);
});
break;
}
loopCandidate = loopCandidate.getParent();
}
if (report && (IGNORE_INCLUDES || !this.hasIncludes(scope)) && !this.hasGotos(scope)) {
holder.registerProblem(variable, String.format(MessagesPresentationUtil.prefixWithEa(messagePattern), variableName), ProblemHighlightType.GENERIC_ERROR);
}
}
break;
}
}
}
}
}
@NotNull
private Set<String> getSuppliedVariables(@NotNull PsiElement expression) {
final Set<String> result = new HashSet<>();
final Function scope = ExpressionSemanticUtil.getScope(expression);
if (scope != null) {
for (final Parameter parameter : scope.getParameters()) {
result.add(parameter.getName());
}
final List<Variable> used = ExpressionSemanticUtil.getUseListVariables(scope);
if (used != null && !used.isEmpty()) {
used.forEach(v -> result.add(v.getName()));
used.clear();
}
}
return result;
}
private boolean hasIncludes(@NotNull Function function) {
final GroupStatement body = ExpressionSemanticUtil.getGroupStatement(function);
if (body != null) {
return PsiTreeUtil.findChildOfType(body, Include.class) != null;
}
return false;
}
private boolean hasGotos(@NotNull Function function) {
final GroupStatement body = ExpressionSemanticUtil.getGroupStatement(function);
if (body != null) {
return PsiTreeUtil.findChildOfType(body, PhpGoto.class) != null;
}
return false;
}
};
}
use of com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor in project phpinspectionsea by kalessil.
the class UnknownInspectionInspector method buildVisitor.
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new BasePhpElementVisitor() {
@Override
public void visitPhpDocTag(@NotNull PhpDocTag tag) {
if (tag.getName().equals("@noinspection")) {
final String[] candidates = tag.getTagValue().replaceAll("[^\\p{L}\\p{Nd}]+", " ").trim().split("\\s+");
if (candidates.length > 0) {
final List<String> unknown = Stream.of(candidates[0]).filter(c -> !inspections.contains(c) && !inspections.contains(c + "Inspection")).collect(Collectors.toList());
if (!unknown.isEmpty()) {
final PsiElement target = tag.getFirstChild();
if (target != null) {
holder.registerProblem(target, String.format(MessagesPresentationUtil.prefixWithEa(message), String.join(", ", unknown)));
}
unknown.clear();
}
}
}
}
};
}
use of com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor in project phpinspectionsea by kalessil.
the class UnnecessaryIssetArgumentsInspector method buildVisitor.
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new BasePhpElementVisitor() {
@Override
public void visitPhpIsset(@NotNull PhpIsset issetExpression) {
final PsiElement[] arguments = issetExpression.getVariables();
if (arguments.length > 1) {
final Set<PsiElement> reported = new HashSet<>();
for (final PsiElement current : arguments) {
if (current instanceof ArrayAccessExpression && !reported.contains(current)) {
/* collect current element bases */
final List<PsiElement> bases = new ArrayList<>();
PsiElement base = current;
while (base instanceof ArrayAccessExpression) {
base = ((ArrayAccessExpression) base).getValue();
if (base != null) {
bases.add(base);
}
}
/* iterate arguments once more to match */
if (!bases.isEmpty()) {
for (final PsiElement discoveredBase : bases) {
for (final PsiElement match : arguments) {
if (match != current && !reported.contains(match) && OpenapiEquivalenceUtil.areEqual(discoveredBase, match)) {
holder.registerProblem(match, MessagesPresentationUtil.prefixWithEa(message), ProblemHighlightType.LIKE_UNUSED_SYMBOL, new DropArgumentFix());
reported.add(match);
}
}
}
bases.clear();
}
}
}
reported.clear();
}
}
};
}
Aggregations