Search in sources :

Example 1 with PhpDocType

use of com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocType in project phpinspectionsea by kalessil.

the class ThrowsResolveUtil method collectThrownAndInherited.

private static boolean collectThrownAndInherited(@NotNull Method method, @NotNull Collection<PhpClass> exceptionsRegistry, @NotNull Collection<Method> processedMethods, boolean lookupWorkflow) {
    processedMethods.add(method);
    boolean result = false;
    final PhpDocComment annotations = method.getDocComment();
    if (annotations == null) {
        /* if PhpDoc is missing, check workflow; but we'll search only `throw new ...` statements */
        if (lookupWorkflow && !method.isAbstract()) {
            for (final PhpThrow thrown : PsiTreeUtil.findChildrenOfType(method, PhpThrow.class)) {
                final PsiElement argument = thrown.getArgument();
                if (argument instanceof NewExpression) {
                    final PsiElement classReference = ((NewExpression) argument).getClassReference();
                    if (classReference != null) {
                        /* false-positives: lambdas and anonymous classes */
                        if (PsiTreeUtil.getParentOfType(thrown, Function.class) != method) {
                            continue;
                        } else /* false-positives: ALL try-enclosed throw statements */
                        if (PsiTreeUtil.getParentOfType(thrown, Try.class, false, (Class) Method.class) != null) {
                            continue;
                        }
                        final PsiElement clazz = OpenapiResolveUtil.resolveReference((PsiReference) classReference);
                        if (clazz instanceof PhpClass) {
                            exceptionsRegistry.add((PhpClass) clazz);
                        }
                    }
                }
            }
            result = true;
        }
    } else {
        /* find all @throws and remember FQNs, @throws can be combined with @inheritdoc */
        for (final PhpDocTag candidate : PsiTreeUtil.findChildrenOfType(annotations, PhpDocTag.class)) {
            if (candidate.getName().equalsIgnoreCase("@throws")) {
                /* definition styles can differ: single tags, pipe concatenated or combined  */
                for (final PhpDocType type : PsiTreeUtil.findChildrenOfType(candidate, PhpDocType.class)) {
                    final PsiElement clazz = OpenapiResolveUtil.resolveReference(type);
                    if (clazz instanceof PhpClass) {
                        exceptionsRegistry.add((PhpClass) clazz);
                    }
                }
            }
        }
        /* resolve inherit doc tags */
        if (annotations.hasInheritDocTag()) {
            collectInherited(method, exceptionsRegistry, processedMethods);
        }
        result = true;
    }
    return result;
}
Also used : PhpDocTag(com.jetbrains.php.lang.documentation.phpdoc.psi.tags.PhpDocTag) PhpDocComment(com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocComment) PhpDocType(com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocType) PsiElement(com.intellij.psi.PsiElement)

Example 2 with PhpDocType

use of com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocType in project phpinspectionsea by kalessil.

the class NullableVariablesStrategy method isNullableResult.

private static boolean isNullableResult(@NotNull AssignmentExpression assignment, @NotNull Project project) {
    boolean result = false;
    final PsiElement assignmentValue = assignment.getValue();
    /* primary strategy: resolve types and check nullability */
    if (assignmentValue instanceof PhpTypedElement) {
        final PhpType resolved = OpenapiResolveUtil.resolveType((PhpTypedElement) assignmentValue, project);
        if (resolved != null) {
            final Set<String> types = new HashSet<>();
            resolved.filterUnknown().getTypes().forEach(t -> types.add(Types.getType(t)));
            if (types.contains(Types.strNull) || types.contains(Types.strVoid)) {
                types.remove(Types.strNull);
                types.remove(Types.strVoid);
                if (!types.isEmpty()) {
                    result = types.stream().noneMatch(t -> !t.startsWith("\\") && !objectTypes.contains(t));
                }
            }
            types.clear();
        }
    }
    /* secondary strategy: support type specification with `@var <type> <variable>` */
    if (result) {
        final PhpPsiElement variable = assignment.getVariable();
        final PsiElement parent = assignment.getParent();
        if (variable != null && OpenapiTypesUtil.isStatementImpl(parent) && OpenapiTypesUtil.isAssignment(assignment)) {
            final PsiElement previous = ((PhpPsiElement) parent).getPrevPsiSibling();
            if (previous instanceof PhpDocComment) {
                final PhpDocTag[] hints = ((PhpDocComment) previous).getTagElementsByName("@var");
                if (hints.length == 1) {
                    final PhpDocVariable specifiedVariable = PsiTreeUtil.findChildOfType(hints[0], PhpDocVariable.class);
                    if (specifiedVariable != null && specifiedVariable.getName().equals(variable.getName())) {
                        result = Arrays.stream(hints[0].getChildren()).anyMatch(t -> t instanceof PhpDocType && Types.getType(t.getText()).equals(Types.strNull));
                    }
                }
            }
        }
    }
    return result;
}
Also used : PhpDocComment(com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocComment) java.util(java.util) com.jetbrains.php.lang.psi.elements(com.jetbrains.php.lang.psi.elements) IElementType(com.intellij.psi.tree.IElementType) PhpTokenTypes(com.jetbrains.php.lang.lexer.PhpTokenTypes) PhpDocType(com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocType) Collectors(java.util.stream.Collectors) PhpDocTag(com.jetbrains.php.lang.documentation.phpdoc.psi.tags.PhpDocTag) Nullable(org.jetbrains.annotations.Nullable) PsiTreeUtil(com.intellij.psi.util.PsiTreeUtil) com.kalessil.phpStorm.phpInspectionsEA.utils(com.kalessil.phpStorm.phpInspectionsEA.utils) PsiElement(com.intellij.psi.PsiElement) Project(com.intellij.openapi.project.Project) PhpDocVariable(com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocVariable) PhpType(com.jetbrains.php.lang.psi.resolve.types.PhpType) NotNull(org.jetbrains.annotations.NotNull) ProblemsHolder(com.intellij.codeInspection.ProblemsHolder) Condition(com.intellij.openapi.util.Condition) PhpDocType(com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocType) PhpType(com.jetbrains.php.lang.psi.resolve.types.PhpType) PhpDocTag(com.jetbrains.php.lang.documentation.phpdoc.psi.tags.PhpDocTag) PhpDocComment(com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocComment) PhpDocVariable(com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocVariable) PsiElement(com.intellij.psi.PsiElement)

Aggregations

PsiElement (com.intellij.psi.PsiElement)2 PhpDocComment (com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocComment)2 PhpDocType (com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocType)2 PhpDocTag (com.jetbrains.php.lang.documentation.phpdoc.psi.tags.PhpDocTag)2 ProblemsHolder (com.intellij.codeInspection.ProblemsHolder)1 Project (com.intellij.openapi.project.Project)1 Condition (com.intellij.openapi.util.Condition)1 IElementType (com.intellij.psi.tree.IElementType)1 PsiTreeUtil (com.intellij.psi.util.PsiTreeUtil)1 PhpDocVariable (com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocVariable)1 PhpTokenTypes (com.jetbrains.php.lang.lexer.PhpTokenTypes)1 com.jetbrains.php.lang.psi.elements (com.jetbrains.php.lang.psi.elements)1 PhpType (com.jetbrains.php.lang.psi.resolve.types.PhpType)1 com.kalessil.phpStorm.phpInspectionsEA.utils (com.kalessil.phpStorm.phpInspectionsEA.utils)1 java.util (java.util)1 Collectors (java.util.stream.Collectors)1 NotNull (org.jetbrains.annotations.NotNull)1 Nullable (org.jetbrains.annotations.Nullable)1