Skip to content

Commit

Permalink
[#1641] StaticClosureCanBeUsedInspector: new settings
Browse files Browse the repository at this point in the history
  • Loading branch information
ea-inspections-team committed Dec 25, 2021
1 parent 71586e1 commit 9bd5262
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@
import com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor;
import com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpInspection;
import com.kalessil.phpStorm.phpInspectionsEA.openApi.PhpLanguageLevel;
import com.kalessil.phpStorm.phpInspectionsEA.options.OptionsComponent;
import com.kalessil.phpStorm.phpInspectionsEA.utils.*;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import java.util.ArrayList;
import java.util.List;

Expand All @@ -33,6 +35,9 @@
public class StaticClosureCanBeUsedInspector extends BasePhpInspection {
private static final String message = "This closure can be declared as static (better scoping; in some cases can improve performance).";

// Inspection options.
public boolean SUGGEST_FOR_SHORT_FUNCTIONS = true;

@NotNull
@Override
public String getShortName() {
Expand Down Expand Up @@ -67,32 +72,37 @@ public void visitPhpFunction(@NotNull Function function) {
private boolean canBeStatic(@NotNull Function function) {
final boolean isArrowFunction = ! OpenapiTypesUtil.is(function.getFirstChild(), PhpTokenTypes.kwFUNCTION);
final PsiElement body = isArrowFunction ? function : ExpressionSemanticUtil.getGroupStatement(function);
if (body != null && (isArrowFunction || ExpressionSemanticUtil.countExpressionsInGroup((GroupStatement) body) > 0)) {
/* check if $this or parent:: being used */
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")) {
return false;
}
} 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()) {
if (body != null) {
final boolean isTargetClosure = (isArrowFunction && SUGGEST_FOR_SHORT_FUNCTIONS) ||
ExpressionSemanticUtil.countExpressionsInGroup((GroupStatement) body) > 0;
if (isTargetClosure) {
/* check if $this or parent:: being used */
for (final PsiElement element : PsiTreeUtil.findChildrenOfAnyType(body, Variable.class, MethodReference.class)) {
if (element instanceof Variable) {
if (((Variable) element).getName().equals("this")) {
return false;
}
} 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()) {
return false;
}
}
}
}
}
/* check usages: perhaps bound to closure or returned -> then we can not promote */
/* Closure::bind(, null, ) -> can be static */
if (! this.canBeStatic(this.usages(function))) {
return false;
/* check usages: perhaps bound to closure or returned -> then we can not promote */
/* Closure::bind(, null, ) -> can be static */
if (! this.canBeStatic(this.usages(function))) {
return false;
}

return true;
}
}
return body != null;
return false;
}

private List<PsiElement> usages(@NotNull Function function) {
Expand Down Expand Up @@ -218,4 +228,10 @@ public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descri
}
}
}

public JComponent createOptionsPanel() {
return OptionsComponent.create((component) ->
component.addCheckbox("Suggest for short functions", SUGGEST_FOR_SHORT_FUNCTIONS, (isSelected) -> SUGGEST_FOR_SHORT_FUNCTIONS = isSelected)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ public void testIfFindsArrowFunctionPatterns() {
final PhpLanguageLevel level = PhpLanguageLevel.parse("7.4");
if (level != null && level.getVersionString().equals("7.4")) {
/* looks like 7.4 feature were introduced in multiple batches */
final boolean hasArrowFunctions = Arrays.stream(PhpLanguageFeature.class.getEnumConstants())
.anyMatch(f -> f.toString().contains("Arrow function"));
final boolean hasArrowFunctions = Arrays.stream(PhpLanguageFeature.class.getEnumConstants()).anyMatch(f -> f.toString().contains("Arrow function"));
if (hasArrowFunctions) {
PhpProjectConfigurationFacade.getInstance(myFixture.getProject()).setLanguageLevel(level);
myFixture.enableInspections(new StaticClosureCanBeUsedInspector());
final StaticClosureCanBeUsedInspector inspection = new StaticClosureCanBeUsedInspector();
inspection.SUGGEST_FOR_SHORT_FUNCTIONS = true;
myFixture.enableInspections(inspection);
myFixture.configureByFile("testData/fixtures/codeStyle/static-closure-use.php74.php");
myFixture.testHighlighting(true, false, true);
}
Expand Down

0 comments on commit 9bd5262

Please sign in to comment.