use of com.jetbrains.php.lang.psi.elements.MethodReference in project phpinspectionsea by kalessil.
the class ImplicitMagicMethodCallInspector method buildVisitor.
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new BasePhpElementVisitor() {
@Override
public void visitPhpMethodReference(@NotNull MethodReference reference) {
final String methodName = reference.getName();
if (methodName != null && methods.contains(methodName)) {
/* Pattern 1: direct calls ob objects */
final String referenceObject = reference.getFirstChild().getText().trim();
if (!referenceObject.equals("$this") && !this.isTestContext(reference)) {
if (!(reference.getFirstChild() instanceof ClassReference) && !referenceObject.equals("parent")) {
/* __toString is a special case */
if (SUGGEST_USING_STRING_CASTING && methodName.equals("__toString")) {
final String message = patternStringCasting.replace("%o%", referenceObject);
holder.registerProblem(reference, message, new UseStringCastingLocalFix());
return;
}
/* allow calling __toString, as a developer don't want hints on this */
if (!SUGGEST_USING_STRING_CASTING && methodName.equals("__toString")) {
return;
}
/* generally reported cases */
holder.registerProblem(reference, message);
return;
}
/* Pattern 2: internal calls inside class methods */
final Function method = ExpressionSemanticUtil.getScope(reference);
if (null != method && !method.getName().equals(methodName)) {
/* allow __construct inside unserialize */
if (methodName.equals("__construct") && method.getName().equals("unserialize")) {
return;
}
/* allow calling __toString, as a developer don't want hints on this */
if (!SUGGEST_USING_STRING_CASTING && methodName.equals("__toString")) {
return;
}
holder.registerProblem(reference, message);
}
}
}
}
};
}
use of com.jetbrains.php.lang.psi.elements.MethodReference in project phpinspectionsea by kalessil.
the class UnnecessaryAssertionInspector method buildVisitor.
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new BasePhpElementVisitor() {
@Override
public void visitPhpMethodReference(@NotNull MethodReference reference) {
final Project project = holder.getProject();
final PhpLanguageLevel php = PhpProjectConfigurationFacade.getInstance(project).getLanguageLevel();
if (!php.hasFeature(PhpLanguageFeature.RETURN_TYPES)) {
return;
}
final String methodName = reference.getName();
if (methodName != null && methodName.startsWith("assert") && targetPositions.containsKey(methodName)) {
final int position = targetPositions.get(methodName);
final PsiElement[] arguments = reference.getParameters();
if (arguments.length >= position + 1 && arguments[position] instanceof FunctionReference) {
final FunctionReference call = (FunctionReference) arguments[position];
final PsiElement function = OpenapiResolveUtil.resolveReference(call);
if (function instanceof Function && OpenapiElementsUtil.getReturnType((Function) function) != null) {
final PhpType resolved = OpenapiResolveUtil.resolveType(call, project);
if (resolved != null && !resolved.hasUnknown() && resolved.size() == 1) {
final String expected = targetType.get(methodName);
if (expected == null || resolved.getTypes().stream().anyMatch(type -> Types.getType(type).equals(expected))) {
holder.registerProblem(reference, message);
}
}
}
}
}
}
};
}
use of com.jetbrains.php.lang.psi.elements.MethodReference in project phpinspectionsea by kalessil.
the class QueryUsageStrategy method apply.
public static void apply(@NotNull MethodReference reference, @NotNull ProblemsHolder holder) {
final String methodName = reference.getName();
if (methodName == null || !methodName.equals("execute")) {
return;
}
final PsiElement[] arguments = reference.getParameters();
if (arguments.length > 0) {
return;
}
/* inspect preceding and succeeding statement */
final PsiElement parent = reference.getParent();
PsiElement predecessor = null;
if (OpenapiTypesUtil.isStatementImpl(parent)) {
predecessor = ((Statement) parent).getPrevPsiSibling();
while (predecessor instanceof PhpDocComment) {
predecessor = ((PhpDocComment) predecessor).getPrevPsiSibling();
}
}
if (null != predecessor && predecessor.getFirstChild() instanceof AssignmentExpression) {
/* predecessor needs to be an assignment */
final AssignmentExpression assignment = (AssignmentExpression) predecessor.getFirstChild();
if (!(assignment.getValue() instanceof MethodReference)) {
return;
}
final MethodReference precedingReference = (MethodReference) assignment.getValue();
if (MethodIdentityUtil.isReferencingMethod(precedingReference, "\\PDO", "prepare")) {
final PsiElement variableAssigned = assignment.getVariable();
final PsiElement variableUsed = reference.getClassReference();
if (variableAssigned != null && variableUsed != null && OpeanapiEquivalenceUtil.areEqual(variableAssigned, variableUsed)) {
holder.registerProblem(reference, message, new UseQueryFix(precedingReference));
}
}
}
}
use of com.jetbrains.php.lang.psi.elements.MethodReference in project phpinspectionsea by kalessil.
the class CallableReferenceNameMismatchInspector method buildVisitor.
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new BasePhpElementVisitor() {
@Override
public void visitPhpMethodReference(@NotNull MethodReference reference) {
final String methodName = reference.getName();
if (methodName != null && !methodName.isEmpty()) {
this.inspectCaseIdentity(reference, methodName, false);
}
}
@Override
public void visitPhpFunctionCall(@NotNull FunctionReference reference) {
final String functionName = reference.getName();
if (functionName != null && !functionName.isEmpty() && !cache.containsKey(functionName)) {
this.inspectCaseIdentity(reference, functionName, true);
}
}
private void inspectCaseIdentity(@NotNull FunctionReference reference, @NotNull String referenceName, boolean useCache) {
/* resolve callable and ensure the case matches */
final PsiElement resolved = OpenapiResolveUtil.resolveReference(reference);
if (resolved instanceof Function) {
final Function function = (Function) resolved;
final String realName = function.getName();
if (useCache && function.getFQN().equals('\\' + realName)) {
cache.putIfAbsent(realName, realName);
}
if (!realName.equals(referenceName) && realName.equalsIgnoreCase(referenceName)) {
holder.registerProblem(reference, messagePattern.replace("%n%", realName), new CallableReferenceNameMismatchQuickFix());
}
}
}
};
}
use of com.jetbrains.php.lang.psi.elements.MethodReference in project yii2support by nvlad.
the class ViewMissedPhpDocInspection method buildVisitor.
@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder problemsHolder, boolean b) {
return new PhpElementVisitor() {
@Override
public void visitPhpFile(PhpFile PhpFile) {
Project project = PhpFile.getProject();
ViewResolve resolve = ViewUtil.resolveView(PhpFile.getVirtualFile(), project);
if (resolve == null) {
return;
}
Map<String, String> params = getVariables(PhpFile);
Map<String, String> declaredVariables = new HashMap<>();
Collection<PhpDocVariable> variableCollection = PsiTreeUtil.findChildrenOfType(PhpFile, PhpDocVariable.class);
for (PhpDocVariable variable : variableCollection) {
declaredVariables.put(variable.getName(), variable.getType().toString());
}
Map<String, String> missedVariables = new HashMap<>();
for (String variableName : params.keySet()) {
if (!declaredVariables.containsKey(variableName)) {
missedVariables.put(variableName, params.get(variableName));
}
}
if (missedVariables.isEmpty()) {
return;
}
String problemDescription = "Missed View variable declaration.";
ViewMissedPhpDocLocalQuickFix quickFix = new ViewMissedPhpDocLocalQuickFix(PhpFile, missedVariables);
problemsHolder.registerProblem(PhpFile, problemDescription, quickFix);
}
private Map<String, String> getVariables(PhpFile phpFile) {
Collection<PsiReference> references = ReferencesSearch.search(phpFile).findAll();
Map<String, String> result = new HashMap<>();
Map<String, PhpType> viewArgumentCollection = new LinkedHashMap<>();
for (PsiReference reference : references) {
MethodReference methodReference = PsiTreeUtil.getParentOfType(reference.getElement(), MethodReference.class);
if (methodReference == null) {
continue;
}
Map<String, PhpType> params = RenderUtil.getViewArguments(methodReference);
for (Map.Entry<String, PhpType> entry : params.entrySet()) {
if (viewArgumentCollection.containsKey(entry.getKey())) {
PhpType.PhpTypeBuilder typeBuilder = new PhpType.PhpTypeBuilder();
typeBuilder.add(viewArgumentCollection.get(entry.getKey()));
typeBuilder.add(entry.getValue());
viewArgumentCollection.replace(entry.getKey(), typeBuilder.build());
} else {
viewArgumentCollection.put(entry.getKey(), entry.getValue());
}
}
}
for (String key : viewArgumentCollection.keySet()) {
result.put(key, viewArgumentCollection.get(key).toString());
}
return result;
}
};
}
Aggregations