Search in sources :

Example 1 with Function

use of com.jetbrains.php.lang.psi.elements.Function 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 2 with Function

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

the class AssertFileEqualsStrategy method apply.

public static boolean apply(@NotNull String methodName, @NotNull MethodReference reference, @NotNull ProblemsHolder holder) {
    boolean result = false;
    if (targetAssertions.contains(methodName)) {
        final PsiElement[] assertionArguments = reference.getParameters();
        if (assertionArguments.length > 1) {
            /* try extracting file_get_contents arguments */
            final List<PsiElement> extracts = Arrays.stream(assertionArguments).map(argument -> {
                PsiElement mappingResult = null;
                if (OpenapiTypesUtil.isFunctionReference(argument)) {
                    final FunctionReference candidate = (FunctionReference) argument;
                    final String functionName = candidate.getName();
                    if (functionName != null && functionName.equals("file_get_contents")) {
                        final PsiElement[] functionArguments = candidate.getParameters();
                        if (functionArguments.length == 1) {
                            mappingResult = functionArguments[0];
                        }
                    }
                }
                return mappingResult;
            }).collect(Collectors.toList());
            /* now check if reporting is needed */
            if (extracts.size() > 1) {
                final Function scope = ExpressionSemanticUtil.getScope(reference);
                final boolean shouldReport = scope == null || !scope.getName().equals("assertFileEquals");
                if (shouldReport) {
                    String[] suggestedArguments = null;
                    if (methodName.equals("assertStringEqualsFile") && extracts.get(1) != null) {
                        suggestedArguments = new String[assertionArguments.length];
                        suggestedArguments[0] = assertionArguments[0].getText();
                        suggestedArguments[1] = extracts.get(1).getText();
                        if (assertionArguments.length > 2) {
                            suggestedArguments[2] = assertionArguments[2].getText();
                        }
                    } else if (extracts.get(0) != null && extracts.get(1) != null) {
                        suggestedArguments = new String[assertionArguments.length];
                        suggestedArguments[0] = extracts.get(0).getText();
                        suggestedArguments[1] = extracts.get(1).getText();
                        if (assertionArguments.length > 2) {
                            suggestedArguments[2] = assertionArguments[2].getText();
                        }
                    }
                    if (suggestedArguments != null) {
                        final String suggestedAssertion = "assertFileEquals";
                        holder.registerProblem(reference, String.format(MessagesPresentationUtil.prefixWithEa(messagePattern), suggestedAssertion), new PhpUnitAssertFixer(suggestedAssertion, suggestedArguments));
                        result = true;
                    }
                }
            }
            extracts.clear();
        }
    }
    return result;
}
Also used : Arrays(java.util.Arrays) ExpressionSemanticUtil(com.kalessil.phpStorm.phpInspectionsEA.utils.ExpressionSemanticUtil) Function(com.jetbrains.php.lang.psi.elements.Function) Set(java.util.Set) MethodReference(com.jetbrains.php.lang.psi.elements.MethodReference) Collectors(java.util.stream.Collectors) HashSet(java.util.HashSet) OpenapiTypesUtil(com.kalessil.phpStorm.phpInspectionsEA.utils.OpenapiTypesUtil) List(java.util.List) MessagesPresentationUtil(com.kalessil.phpStorm.phpInspectionsEA.utils.MessagesPresentationUtil) PsiElement(com.intellij.psi.PsiElement) FunctionReference(com.jetbrains.php.lang.psi.elements.FunctionReference) NotNull(org.jetbrains.annotations.NotNull) PhpUnitAssertFixer(com.kalessil.phpStorm.phpInspectionsEA.fixers.PhpUnitAssertFixer) ProblemsHolder(com.intellij.codeInspection.ProblemsHolder) Function(com.jetbrains.php.lang.psi.elements.Function) PhpUnitAssertFixer(com.kalessil.phpStorm.phpInspectionsEA.fixers.PhpUnitAssertFixer) FunctionReference(com.jetbrains.php.lang.psi.elements.FunctionReference) PsiElement(com.intellij.psi.PsiElement)

Example 3 with Function

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

the class AssertStringEqualsFileStrategy method apply.

public static boolean apply(@NotNull String methodName, @NotNull MethodReference reference, @NotNull ProblemsHolder holder) {
    boolean result = false;
    if (targetAssertions.contains(methodName)) {
        final PsiElement[] assertionArguments = reference.getParameters();
        if (assertionArguments.length > 1 && OpenapiTypesUtil.isFunctionReference(assertionArguments[0])) {
            final FunctionReference candidate = (FunctionReference) assertionArguments[0];
            final String functionName = candidate.getName();
            if (functionName != null && functionName.equals("file_get_contents")) {
                final PsiElement[] functionArguments = candidate.getParameters();
                if (functionArguments.length == 1) {
                    final Function scope = ExpressionSemanticUtil.getScope(reference);
                    final boolean shouldReport = scope == null || !validContexts.contains(scope.getName());
                    if (shouldReport) {
                        final String[] suggestedArguments = new String[assertionArguments.length];
                        suggestedArguments[0] = functionArguments[0].getText();
                        suggestedArguments[1] = assertionArguments[1].getText();
                        if (assertionArguments.length > 2) {
                            suggestedArguments[2] = assertionArguments[2].getText();
                        }
                        final String suggestedAssertion = "assertStringEqualsFile";
                        holder.registerProblem(reference, String.format(MessagesPresentationUtil.prefixWithEa(messagePattern), suggestedAssertion), new PhpUnitAssertFixer(suggestedAssertion, suggestedArguments));
                        result = true;
                    }
                }
            }
        }
    }
    return result;
}
Also used : Function(com.jetbrains.php.lang.psi.elements.Function) PhpUnitAssertFixer(com.kalessil.phpStorm.phpInspectionsEA.fixers.PhpUnitAssertFixer) FunctionReference(com.jetbrains.php.lang.psi.elements.FunctionReference) PsiElement(com.intellij.psi.PsiElement)

Example 4 with Function

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

the class EncryptionInitializationVectorRandomnessInspector method buildVisitor.

@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
    return new BasePhpElementVisitor() {

        @Override
        public void visitPhpFunctionCall(@NotNull FunctionReference reference) {
            final String functionName = reference.getName();
            /* variable functions are not supported, as we are checking 2 different extensions functions */
            if (functionName != null && (functionName.equals("openssl_encrypt") || functionName.equals("mcrypt_encrypt"))) {
                final PsiElement[] arguments = reference.getParameters();
                if (arguments.length != 5 || arguments[4] == null || arguments[4].getText().isEmpty()) {
                    return;
                }
                /* discover and inspect possible values */
                final Set<PsiElement> values = PossibleValuesDiscoveryUtil.discover(arguments[4]);
                if (!values.isEmpty()) {
                    /* check all possible values */
                    final List<String> reporting = new ArrayList<>();
                    for (final PsiElement source : values) {
                        if (OpenapiTypesUtil.isFunctionReference(source)) {
                            final String sourceName = ((FunctionReference) source).getName();
                            if (sourceName != null && secureFunctions.contains(sourceName)) {
                                continue;
                            }
                        }
                        reporting.add(source.getText());
                    }
                    if (!reporting.isEmpty() && !this.isAggregatedGeneration(values)) {
                        /* sort reporting list to produce testable results */
                        Collections.sort(reporting);
                        final String ivFunction = functionName.startsWith("openssl_") ? "openssl_random_pseudo_bytes" : "mcrypt_create_iv";
                        holder.registerProblem(arguments[4], MessagesPresentationUtil.prefixWithEa(String.format(messagePattern, ivFunction, String.join(", ", reporting))), ProblemHighlightType.GENERIC_ERROR);
                    }
                    reporting.clear();
                }
                values.clear();
            }
        }

        private boolean isAggregatedGeneration(@NotNull Set<PsiElement> candidates) {
            if (candidates.size() == 1) {
                final PsiElement candidate = candidates.iterator().next();
                if (candidate instanceof FunctionReference) {
                    final PsiElement resolved = OpenapiResolveUtil.resolveReference((PsiReference) candidate);
                    if (resolved instanceof Function) {
                        final GroupStatement body = ExpressionSemanticUtil.getGroupStatement(resolved);
                        if (body != null) {
                            return PsiTreeUtil.findChildrenOfType(body, FunctionReference.class).stream().anyMatch(c -> secureFunctions.contains(c.getName()));
                        }
                    }
                }
            }
            return false;
        }
    };
}
Also used : BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) Function(com.jetbrains.php.lang.psi.elements.Function) GroupStatement(com.jetbrains.php.lang.psi.elements.GroupStatement) FunctionReference(com.jetbrains.php.lang.psi.elements.FunctionReference) NotNull(org.jetbrains.annotations.NotNull) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 5 with Function

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

the class SwitchContinuationInLoopInspector method buildVisitor.

@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
    return new BasePhpElementVisitor() {

        @Override
        public void visitPhpContinue(@NotNull PhpContinue continueStatement) {
            /* check if continue already defined with desired level */
            if (null != continueStatement.getFirstPsiChild()) {
                return;
            }
            boolean isSwitch = false;
            PsiElement objParent = continueStatement.getParent();
            while (null != objParent) {
                /* reached file or callable */
                if (objParent instanceof PhpFile || objParent instanceof Function) {
                    return;
                }
                /* check if should operate on loop-switch-continue analysis */
                if (!isSwitch && objParent instanceof PhpSwitch) {
                    isSwitch = true;
                }
                /* when met a loop, complete analysis */
                if (OpenapiTypesUtil.isLoop(objParent)) {
                    if (isSwitch) {
                        holder.registerProblem(continueStatement, MessagesPresentationUtil.prefixWithEa(message), ProblemHighlightType.GENERIC_ERROR, new UseContinue2LocalFix());
                    }
                    return;
                }
                objParent = objParent.getParent();
            }
        }
    };
}
Also used : BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) Function(com.jetbrains.php.lang.psi.elements.Function) PhpFile(com.jetbrains.php.lang.psi.PhpFile) PhpContinue(com.jetbrains.php.lang.psi.elements.PhpContinue) PhpSwitch(com.jetbrains.php.lang.psi.elements.PhpSwitch) NotNull(org.jetbrains.annotations.NotNull) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

Function (com.jetbrains.php.lang.psi.elements.Function)11 NotNull (org.jetbrains.annotations.NotNull)9 PsiElement (com.intellij.psi.PsiElement)8 BasePhpElementVisitor (com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor)8 FunctionReference (com.jetbrains.php.lang.psi.elements.FunctionReference)5 MethodReference (com.jetbrains.php.lang.psi.elements.MethodReference)3 ProblemsHolder (com.intellij.codeInspection.ProblemsHolder)2 GroupStatement (com.jetbrains.php.lang.psi.elements.GroupStatement)2 Method (com.jetbrains.php.lang.psi.elements.Method)2 Parameter (com.jetbrains.php.lang.psi.elements.Parameter)2 PhpUnitAssertFixer (com.kalessil.phpStorm.phpInspectionsEA.fixers.PhpUnitAssertFixer)2 MessagesPresentationUtil (com.kalessil.phpStorm.phpInspectionsEA.utils.MessagesPresentationUtil)2 List (java.util.List)2 PsiElementVisitor (com.intellij.psi.PsiElementVisitor)1 PhpIndex (com.jetbrains.php.PhpIndex)1 PhpScopeHolder (com.jetbrains.php.codeInsight.PhpScopeHolder)1 PhpAccessVariableInstruction (com.jetbrains.php.codeInsight.controlFlow.instructions.PhpAccessVariableInstruction)1 PhpEntryPointInstruction (com.jetbrains.php.codeInsight.controlFlow.instructions.PhpEntryPointInstruction)1 PhpFile (com.jetbrains.php.lang.psi.PhpFile)1 ClassReference (com.jetbrains.php.lang.psi.elements.ClassReference)1