use of com.jetbrains.php.lang.psi.elements.PhpClass in project phpinspectionsea by kalessil.
the class MagicMethodsValidityInspector method buildVisitor.
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly) {
return new BasePhpElementVisitor() {
@Override
public void visitPhpMethod(@NotNull Method method) {
final PhpClass clazz = method.getContainingClass();
final String methodName = method.getName();
final PsiElement nameNode = NamedElementUtil.getNameIdentifier(method);
if (clazz == null || nameNode == null || !methodName.startsWith("_") || method.isAbstract()) {
return;
}
switch(methodName) {
case "__construct":
CanNotBeStaticStrategy.apply(method, holder);
CanNotReturnTypeStrategy.apply(method, holder);
if (!this.isTestContext(clazz)) {
NormallyCallsParentMethodStrategy.apply(method, holder);
}
break;
case "__destruct":
case "__clone":
CanNotBeStaticStrategy.apply(method, holder);
CanNotReturnTypeStrategy.apply(method, holder);
CanNotTakeArgumentsStrategy.apply(method, holder);
NormallyCallsParentMethodStrategy.apply(method, holder);
break;
case "__get":
case "__isset":
case "__unset":
TakesExactAmountOfArgumentsStrategy.apply(1, method, holder);
CanNotBeStaticStrategy.apply(method, holder);
MustBePublicStrategy.apply(method, holder);
CanNotTakeArgumentsByReferenceStrategy.apply(method, holder);
HasAlsoMethodStrategy.apply(method, "__set", holder);
break;
case "__set":
case "__call":
TakesExactAmountOfArgumentsStrategy.apply(2, method, holder);
CanNotBeStaticStrategy.apply(method, holder);
MustBePublicStrategy.apply(method, holder);
CanNotTakeArgumentsByReferenceStrategy.apply(method, holder);
if (methodName.equals("__set")) {
HasAlsoMethodStrategy.apply(method, "__isset", holder);
HasAlsoMethodStrategy.apply(method, "__get", holder);
}
break;
case "__callStatic":
TakesExactAmountOfArgumentsStrategy.apply(2, method, holder);
MustBeStaticStrategy.apply(method, holder);
MustBePublicStrategy.apply(method, holder);
CanNotTakeArgumentsByReferenceStrategy.apply(method, holder);
break;
case "__toString":
CanNotBeStaticStrategy.apply(method, holder);
CanNotTakeArgumentsStrategy.apply(method, holder);
MustBePublicStrategy.apply(method, holder);
MustReturnSpecifiedTypeStrategy.apply(stringType, method, holder);
break;
case "__debugInfo":
CanNotBeStaticStrategy.apply(method, holder);
CanNotTakeArgumentsStrategy.apply(method, holder);
MustBePublicStrategy.apply(method, holder);
MustReturnSpecifiedTypeStrategy.apply(arrayOrNullType, method, holder);
MinimalPhpVersionStrategy.apply(method, holder, PhpLanguageLevel.PHP560);
break;
case "__set_state":
TakesExactAmountOfArgumentsStrategy.apply(1, method, holder);
MustBeStaticStrategy.apply(method, holder);
MustBePublicStrategy.apply(method, holder);
final PhpType returnTypes = (new PhpType()).add(clazz.getFQN()).add(Types.strStatic);
MustReturnSpecifiedTypeStrategy.apply(returnTypes, method, holder);
break;
case "__invoke":
CanNotBeStaticStrategy.apply(method, holder);
MustBePublicStrategy.apply(method, holder);
break;
case "__wakeup":
CanNotBeStaticStrategy.apply(method, holder);
CanNotTakeArgumentsStrategy.apply(method, holder);
CanNotReturnTypeStrategy.apply(method, holder);
break;
case "__unserialize":
CanNotBeStaticStrategy.apply(method, holder);
MustBePublicStrategy.apply(method, holder);
TakesExactAmountOfArgumentsStrategy.apply(1, method, holder);
CanNotReturnTypeStrategy.apply(method, holder);
break;
case "__sleep":
case "__serialize":
CanNotBeStaticStrategy.apply(method, holder);
MustBePublicStrategy.apply(method, holder);
CanNotTakeArgumentsStrategy.apply(method, holder);
MustReturnSpecifiedTypeStrategy.apply(arrayType, method, holder);
break;
case "__autoload":
TakesExactAmountOfArgumentsStrategy.apply(1, method, holder);
CanNotReturnTypeStrategy.apply(method, holder);
holder.registerProblem(nameNode, MessagesPresentationUtil.prefixWithEa(messageUseSplAutoloading), ProblemHighlightType.LIKE_DEPRECATED);
break;
default:
if (methodName.startsWith("__") && !knownNonMagic.contains(methodName)) {
holder.registerProblem(nameNode, MessagesPresentationUtil.prefixWithEa(messageNotMagic));
} else {
MissingUnderscoreStrategy.apply(method, holder);
}
break;
}
}
};
}
use of com.jetbrains.php.lang.psi.elements.PhpClass in project phpinspectionsea by kalessil.
the class AutoloadingIssuesInspector method buildVisitor.
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new BasePhpElementVisitor() {
@Override
public void visitPhpFile(@NotNull PhpFile file) {
final String fileName = file.getName();
if (fileName.endsWith(".php") && !ignoredFiles.contains(fileName) && !laravelMigration.matcher(fileName).matches()) {
final List<PhpClass> classes = new ArrayList<>();
file.getTopLevelDefs().values().stream().filter(definition -> definition instanceof PhpClass).forEach(definition -> classes.add((PhpClass) definition));
if (classes.size() == 1) {
final PhpClass clazz = classes.get(0);
final String className = clazz.getName();
/* PSR-0 classloading (Package_Subpackage_Class) naming */
String extractedClassName = className;
if (clazz.getFQN().lastIndexOf('\\') == 0 && extractedClassName.indexOf('_') != -1) {
extractedClassName = extractedClassName.substring(1 + extractedClassName.lastIndexOf('_'));
}
/* check the file name as per extraction compliant with PSR-0/PSR-4 standards */
final String expectedClassName = fileName.substring(0, fileName.indexOf('.'));
if (this.isBreakingPsrStandard(className, expectedClassName, extractedClassName) && !this.isWordpressStandard(className, fileName)) {
final PsiElement classNameNode = NamedElementUtil.getNameIdentifier(clazz);
if (classNameNode != null) {
holder.registerProblem(classNameNode, MessagesPresentationUtil.prefixWithEa(message));
}
}
}
classes.clear();
}
}
private boolean isBreakingPsrStandard(@NotNull String className, @NotNull String expectedClassName, @NotNull String extractedClassName) {
return !expectedClassName.equals(extractedClassName) && !expectedClassName.equals(className);
}
private boolean isWordpressStandard(@NotNull String className, @NotNull String fileName) {
final String wordpressFileName = String.format("class-%s.php", className.toLowerCase().replaceAll("_", "-"));
return fileName.endsWith(wordpressFileName);
}
};
}
use of com.jetbrains.php.lang.psi.elements.PhpClass in project phpinspectionsea by kalessil.
the class ClassMethodNameMatchesFieldNameInspector method buildVisitor.
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new BasePhpElementVisitor() {
@Override
public void visitPhpMethod(@NotNull Method method) {
final PhpClass clazz = method.getContainingClass();
if (clazz != null && !clazz.isInterface()) {
final Field field = OpenapiResolveUtil.resolveField(clazz, method.getName());
if (field != null) {
final PsiElement nameNode = NamedElementUtil.getNameIdentifier(method);
final PhpType resolvedType = OpenapiResolveUtil.resolveType(field, holder.getProject());
if (resolvedType != null && nameNode != null) {
final PhpType knownType = resolvedType.filterUnknown();
if (knownType.isEmpty()) {
holder.registerProblem(nameNode, MessagesPresentationUtil.prefixWithEa(messageFieldType));
} else {
final boolean isCallable = knownType.getTypes().stream().anyMatch(t -> Types.getType(t).equals(Types.strCallable));
if (isCallable) {
holder.registerProblem(nameNode, MessagesPresentationUtil.prefixWithEa(messageMatches));
}
}
}
}
}
}
};
}
use of com.jetbrains.php.lang.psi.elements.PhpClass in project phpinspectionsea by kalessil.
the class DeprecatedConstructorStyleInspector method buildVisitor.
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new BasePhpElementVisitor() {
@Override
public void visitPhpMethod(@NotNull Method method) {
if (!method.isStatic()) {
final PhpClass clazz = method.getContainingClass();
final PsiElement nameNode = NamedElementUtil.getNameIdentifier(method);
if (clazz != null && nameNode != null && !clazz.isTrait() && !clazz.isInterface()) {
final String className = clazz.getName();
if (className.equals(method.getName()) && clazz.findOwnMethodByName("__construct") == null) {
holder.registerProblem(nameNode, MessagesPresentationUtil.prefixWithEa(String.format(messagePattern, className)), ProblemHighlightType.LIKE_DEPRECATED, new RenameConstructorFix());
}
}
}
}
};
}
use of com.jetbrains.php.lang.psi.elements.PhpClass in project phpinspectionsea by kalessil.
the class EmptyClassInspector method buildVisitor.
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new BasePhpElementVisitor() {
@Override
public void visitPhpClass(@NotNull PhpClass clazz) {
if (!clazz.isInterface() && !clazz.isDeprecated() && !clazz.isAnonymous()) {
final boolean isEmpty = clazz.getOwnFields().length == 0 && clazz.getOwnMethods().length == 0 && clazz.getTraits().length == 0;
if (isEmpty) {
final PhpClass parent = OpenapiResolveUtil.resolveSuperClass(clazz);
if (parent != null) {
/* we can be forced to introduce an empty class: abstract parent, exception classes */
final boolean skip = parent.isAbstract() || InterfacesExtractUtil.getCrawlInheritanceTree(clazz, true).stream().anyMatch(c -> c.getFQN().equals("\\Exception"));
if (skip) {
return;
}
}
final PsiElement nameNode = NamedElementUtil.getNameIdentifier(clazz);
if (nameNode != null) {
holder.registerProblem(nameNode, MessagesPresentationUtil.prefixWithEa(message));
}
}
}
}
};
}
Aggregations