Search in sources :

Example 11 with PhpClass

use of com.jetbrains.php.lang.psi.elements.PhpClass in project phpinspectionsea by kalessil.

the class MethodIdentityUtil method isReferencingMethod.

public static boolean isReferencingMethod(@Nullable MethodReference reference, @NotNull String classFqn, @NotNull String methodName) {
    boolean result = false;
    final String referenceName = (null == reference ? null : reference.getName());
    if (referenceName != null && referenceName.equals(methodName)) {
        final PsiElement resolved = OpenapiResolveUtil.resolveReference(reference);
        if (resolved instanceof Method) {
            final Method method = (Method) resolved;
            result = method.getFQN().equals(classFqn + "::" + methodName);
            if (!result) {
                final PhpClass clazz = method.getContainingClass();
                if (clazz != null && !clazz.isTrait()) {
                    final Set<PhpClass> parents = InterfacesExtractUtil.getCrawlInheritanceTree(clazz, true);
                    for (final PhpClass parent : parents) {
                        if (parent.getFQN().equals(classFqn)) {
                            result = true;
                            break;
                        }
                    }
                    parents.clear();
                }
            }
        }
    }
    return result;
}
Also used : PhpClass(com.jetbrains.php.lang.psi.elements.PhpClass) Method(com.jetbrains.php.lang.psi.elements.Method) PsiElement(com.intellij.psi.PsiElement)

Example 12 with PhpClass

use of com.jetbrains.php.lang.psi.elements.PhpClass 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();
                }
            }
        }
    };
}
Also used : PhpClass(com.jetbrains.php.lang.psi.elements.PhpClass) BasePhpInspection(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpInspection) Types(com.kalessil.phpStorm.phpInspectionsEA.utils.Types) PhpLanguageUtil(com.kalessil.phpStorm.phpInspectionsEA.utils.PhpLanguageUtil) Function(com.jetbrains.php.lang.psi.elements.Function) Method(com.jetbrains.php.lang.psi.elements.Method) ArrayList(java.util.ArrayList) BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) List(java.util.List) OpenapiResolveUtil(com.kalessil.phpStorm.phpInspectionsEA.utils.OpenapiResolveUtil) MessagesPresentationUtil(com.kalessil.phpStorm.phpInspectionsEA.utils.MessagesPresentationUtil) PsiElement(com.intellij.psi.PsiElement) Parameter(com.jetbrains.php.lang.psi.elements.Parameter) PhpType(com.jetbrains.php.lang.psi.resolve.types.PhpType) NotNull(org.jetbrains.annotations.NotNull) PsiElementVisitor(com.intellij.psi.PsiElementVisitor) ProblemsHolder(com.intellij.codeInspection.ProblemsHolder) BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) Function(com.jetbrains.php.lang.psi.elements.Function) PhpClass(com.jetbrains.php.lang.psi.elements.PhpClass) ArrayList(java.util.ArrayList) Parameter(com.jetbrains.php.lang.psi.elements.Parameter) Method(com.jetbrains.php.lang.psi.elements.Method) NotNull(org.jetbrains.annotations.NotNull) PsiElement(com.intellij.psi.PsiElement) PhpType(com.jetbrains.php.lang.psi.resolve.types.PhpType) NotNull(org.jetbrains.annotations.NotNull)

Example 13 with PhpClass

use of com.jetbrains.php.lang.psi.elements.PhpClass 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));
                }
            }
        }
    };
}
Also used : BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) PhpClass(com.jetbrains.php.lang.psi.elements.PhpClass) ClassReference(com.jetbrains.php.lang.psi.elements.ClassReference) NotNull(org.jetbrains.annotations.NotNull) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 14 with PhpClass

use of com.jetbrains.php.lang.psi.elements.PhpClass in project phpinspectionsea by kalessil.

the class InterfacesExtractUtil method processClass.

private static void processClass(@NotNull PhpClass clazz, @NotNull Set<PhpClass> processedItems, boolean withClasses) {
    if (!clazz.isInterface()) {
        if (withClasses && !processedItems.add(clazz)) {
            return;
        }
        /* re-delegate interface handling */
        OpenapiResolveUtil.resolveImplementedInterfaces(clazz).forEach(i -> processInterface(i, processedItems));
        /* handle parent class */
        final PhpClass parent = OpenapiResolveUtil.resolveSuperClass(clazz);
        if (parent != null && clazz != parent) {
            processClass(parent, processedItems, withClasses);
        }
    }
}
Also used : PhpClass(com.jetbrains.php.lang.psi.elements.PhpClass)

Example 15 with PhpClass

use of com.jetbrains.php.lang.psi.elements.PhpClass in project phpinspectionsea by kalessil.

the class ClassInStringContextStrategy method apply.

public static boolean apply(@Nullable PsiElement nonStringOperand, @NotNull ProblemsHolder holder, @NotNull PsiElement expression, @NotNull String classHasNoToStringMessage) {
    if (null == nonStringOperand) {
        return false;
    }
    final Set<String> resolvedTypes = new HashSet<>();
    if (nonStringOperand instanceof PhpTypedElement) {
        final PhpType resolved = OpenapiResolveUtil.resolveType((PhpTypedElement) nonStringOperand, holder.getProject());
        if (resolved != null) {
            resolved.filterUnknown().getTypes().forEach(t -> resolvedTypes.add(Types.getType(t)));
        }
    }
    if (!TypesSemanticsUtil.isNullableObjectInterface(resolvedTypes)) {
        resolvedTypes.clear();
        return false;
    }
    /* collect classes to check if __toString() is there */
    final PhpIndex index = PhpIndex.getInstance(holder.getProject());
    final List<PhpClass> listClasses = new ArrayList<>();
    resolvedTypes.stream().filter(fqn -> fqn.charAt(0) == '\\').forEach(fqn -> listClasses.addAll(OpenapiResolveUtil.resolveClassesAndInterfacesByFQN(fqn, index)));
    resolvedTypes.clear();
    /* check methods, error on first one violated requirements */
    for (final PhpClass clazz : listClasses) {
        if (OpenapiResolveUtil.resolveMethod(clazz, "__toString") == null) {
            holder.registerProblem(expression, MessagesPresentationUtil.prefixWithEa(classHasNoToStringMessage.replace("%class%", clazz.getFQN())), ProblemHighlightType.ERROR);
            break;
        }
    }
    /* terminate inspection, php will call __toString() */
    listClasses.clear();
    return true;
}
Also used : PhpClass(com.jetbrains.php.lang.psi.elements.PhpClass) Types(com.kalessil.phpStorm.phpInspectionsEA.utils.Types) TypesSemanticsUtil(com.kalessil.phpStorm.phpInspectionsEA.utils.TypesSemanticsUtil) Set(java.util.Set) PhpIndex(com.jetbrains.php.PhpIndex) PhpTypedElement(com.jetbrains.php.lang.psi.elements.PhpTypedElement) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Nullable(org.jetbrains.annotations.Nullable) List(java.util.List) OpenapiResolveUtil(com.kalessil.phpStorm.phpInspectionsEA.utils.OpenapiResolveUtil) MessagesPresentationUtil(com.kalessil.phpStorm.phpInspectionsEA.utils.MessagesPresentationUtil) PsiElement(com.intellij.psi.PsiElement) ProblemHighlightType(com.intellij.codeInspection.ProblemHighlightType) PhpType(com.jetbrains.php.lang.psi.resolve.types.PhpType) NotNull(org.jetbrains.annotations.NotNull) ProblemsHolder(com.intellij.codeInspection.ProblemsHolder) PhpIndex(com.jetbrains.php.PhpIndex) PhpClass(com.jetbrains.php.lang.psi.elements.PhpClass) ArrayList(java.util.ArrayList) PhpTypedElement(com.jetbrains.php.lang.psi.elements.PhpTypedElement) PhpType(com.jetbrains.php.lang.psi.resolve.types.PhpType) HashSet(java.util.HashSet)

Aggregations

PhpClass (com.jetbrains.php.lang.psi.elements.PhpClass)35 PsiElement (com.intellij.psi.PsiElement)26 NotNull (org.jetbrains.annotations.NotNull)19 BasePhpElementVisitor (com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor)14 Method (com.jetbrains.php.lang.psi.elements.Method)11 PhpIndex (com.jetbrains.php.PhpIndex)8 ProblemsHolder (com.intellij.codeInspection.ProblemsHolder)7 PhpType (com.jetbrains.php.lang.psi.resolve.types.PhpType)7 MessagesPresentationUtil (com.kalessil.phpStorm.phpInspectionsEA.utils.MessagesPresentationUtil)6 OpenapiResolveUtil (com.kalessil.phpStorm.phpInspectionsEA.utils.OpenapiResolveUtil)6 PsiElementVisitor (com.intellij.psi.PsiElementVisitor)5 Field (com.jetbrains.php.lang.psi.elements.Field)5 BasePhpInspection (com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpInspection)5 HashSet (java.util.HashSet)5 Project (com.intellij.openapi.project.Project)4 ClassReference (com.jetbrains.php.lang.psi.elements.ClassReference)4 ArrayList (java.util.ArrayList)4 List (java.util.List)4 ProblemHighlightType (com.intellij.codeInspection.ProblemHighlightType)3 Editor (com.intellij.openapi.editor.Editor)3