Skip to content

Commit

Permalink
Support deprecation Doctrine field types for attributes Haehnchen/ide…
Browse files Browse the repository at this point in the history
  • Loading branch information
Haehnchen committed Nov 28, 2022
1 parent b8c8cb5 commit 001a61d
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,24 @@
import com.intellij.patterns.PlatformPatterns;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiWhiteSpace;
import com.intellij.psi.util.PsiTreeUtil;
import com.jetbrains.php.lang.PhpLangUtil;
import com.jetbrains.php.lang.documentation.phpdoc.lexer.PhpDocTokenTypes;
import com.jetbrains.php.lang.documentation.phpdoc.parser.PhpDocElementTypes;
import com.jetbrains.php.lang.documentation.phpdoc.psi.tags.PhpDocTag;
import com.jetbrains.php.lang.lexer.PhpTokenTypes;
import com.jetbrains.php.lang.psi.PhpPsiUtil;
import com.jetbrains.php.lang.psi.elements.PhpAttribute;
import com.jetbrains.php.lang.psi.elements.PhpClass;
import com.jetbrains.php.lang.psi.elements.StringLiteralExpression;
import de.espend.idea.php.annotation.dict.PhpDocTagAnnotation;
import de.espend.idea.php.annotation.doctrine.util.DoctrineUtil;
import de.espend.idea.php.annotation.pattern.AnnotationPattern;
import de.espend.idea.php.annotation.util.AnnotationUtil;
import de.espend.idea.php.annotation.util.PhpElementsUtil;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
* Check for underlay class deprecations of Column type class from Doctrine
Expand All @@ -44,55 +49,61 @@ public DoctrineTypePropertyVisitor(ProblemsHolder holder) {

@Override
public void visitElement(PsiElement element) {
if (!(element instanceof StringLiteralExpression) || element.getNode().getElementType() != PhpDocElementTypes.phpDocString) {
super.visitElement(element);
return;
}
String contents = foo(element, "\\Doctrine\\ORM\\Mapping\\Column", "type");
if (contents != null) {
for (PhpClass columnPhpClass : DoctrineUtil.getColumnTypesTargets(holder.getProject(), contents)) {
if (!columnPhpClass.isDeprecated()) {
continue;
}

String contents = ((StringLiteralExpression) element).getContents();
if (StringUtils.isBlank(contents)) {
super.visitElement(element);
return;
}
String deprecationMessage = PhpElementsUtil.getClassDeprecatedMessage(columnPhpClass);

PhpDocTag phpDocTag = PsiTreeUtil.getParentOfType(element, PhpDocTag.class);
if (phpDocTag == null) {
super.visitElement(element);
return;
}
holder.registerProblem(
element,
"[Annotations] " + (deprecationMessage != null ? deprecationMessage : String.format("Field '%s' is deprecated", contents)),
ProblemHighlightType.LIKE_DEPRECATED
);

PsiElement propertyName = PhpElementsUtil.getPrevSiblingOfPatternMatch(element, PlatformPatterns.psiElement(PhpDocTokenTypes.DOC_IDENTIFIER));
if(propertyName == null) {
super.visitElement(element);
return;
break;
}
}

String text = propertyName.getText();
if ("type".equalsIgnoreCase(text)) {
PhpDocTagAnnotation phpDocAnnotationContainer = AnnotationUtil.getPhpDocAnnotationContainer(phpDocTag);
if (phpDocAnnotationContainer != null) {
PhpClass tagPhpClass = phpDocAnnotationContainer.getPhpClass();
if (PhpLangUtil.equalsClassNames(tagPhpClass.getPresentableFQN(), "Doctrine\\ORM\\Mapping\\Column")) {
for (PhpClass columnPhpClass : DoctrineUtil.getColumnTypesTargets(holder.getProject(), contents)) {
if (!columnPhpClass.isDeprecated()) {
continue;
}

String deprecationMessage = PhpElementsUtil.getClassDeprecatedMessage(columnPhpClass);

holder.registerProblem(
element,
"[Annotations] " + (deprecationMessage != null ? deprecationMessage : String.format("Field '%s' is deprecated", text)),
ProblemHighlightType.LIKE_DEPRECATED
);
super.visitElement(element);
}
}

break;
@Nullable
private static String foo(@NotNull PsiElement psiElement, @NotNull String clazz, @NotNull String property) {
if (AnnotationPattern.getAttributesValueReferencesPattern().accepts(psiElement)) {
PsiElement attributeNamePsi = PhpPsiUtil.getPrevSibling(psiElement, psiElement1 -> psiElement1 instanceof PsiWhiteSpace || psiElement1.getNode().getElementType() == PhpTokenTypes.opCOLON);
if (attributeNamePsi != null && attributeNamePsi.getNode().getElementType() == PhpTokenTypes.IDENTIFIER) {
String text = attributeNamePsi.getText();
if (text.equals("type")) {
PhpAttribute phpAttribute = PsiTreeUtil.getParentOfType(psiElement, PhpAttribute.class);
if (phpAttribute != null) {
String fqn = phpAttribute.getFQN();
if (fqn != null) {
return ((StringLiteralExpression) psiElement).getContents();
}
}
}
}

super.visitElement(element);
} else {
if (psiElement instanceof StringLiteralExpression && psiElement.getNode().getElementType() == PhpDocElementTypes.phpDocString) {
PsiElement propertyName = PhpElementsUtil.getPrevSiblingOfPatternMatch(psiElement, PlatformPatterns.psiElement(PhpDocTokenTypes.DOC_IDENTIFIER));
if(propertyName != null && property.equals(propertyName.getText())) {
PhpDocTag phpDocTag = PsiTreeUtil.getParentOfType(psiElement, PhpDocTag.class);
if (phpDocTag != null) {
PhpDocTagAnnotation phpDocAnnotationContainer = AnnotationUtil.getPhpDocAnnotationContainer(phpDocTag);
if (phpDocAnnotationContainer != null && PhpLangUtil.equalsClassNames(phpDocAnnotationContainer.getPhpClass().getFQN(), clazz)) {
return ((StringLiteralExpression) psiElement).getContents();
}
}
}
}
}

return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

/**
* @author Daniel Espendiller <daniel@espendiller.net>
* @see de.espend.idea.php.annotation.doctrine.inspection.DoctrineTypeDeprecatedInspection
*/
public class DoctrineTypeDeprecatedInspectionTest extends AnnotationLightCodeInsightFixtureTestCase {
public void setUp() throws Exception {
Expand Down Expand Up @@ -39,4 +40,16 @@ public void testThatDeprecatedInspectionIsDisplayedDoctrineColumnTypes() {
"}"
);
}

public void testThatDeprecatedInspectionIsDisplayedDoctrineColumnTypesForAttribute() {
assertLocalInspectionContains("test.php", "<?php\n" +
"use Doctrine\\ORM\\Mapping as ORM;\n" +
"\n" +
"#[ORM\\Column(type: 'json<caret>_array')]\n" +
"class Foo\n" +
"{\n" +
"}",
"[Annotations] Deprecated: Use JsonType instead"
);
}
}

0 comments on commit 001a61d

Please sign in to comment.