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();
}
}
}
};
}
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;
}
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;
}
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;
}
};
}
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();
}
}
};
}
Aggregations