Package fr.adrienbrault.idea.symfony2plugin.doctrine

Source Code of fr.adrienbrault.idea.symfony2plugin.doctrine.DoctrineAnnotationReferencedColumnReferences

package fr.adrienbrault.idea.symfony2plugin.doctrine;


import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.jetbrains.php.lang.documentation.phpdoc.parser.PhpDocElementTypes;
import com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocComment;
import com.jetbrains.php.lang.psi.elements.PhpClass;
import com.jetbrains.php.lang.psi.elements.PhpPsiElement;
import com.jetbrains.php.lang.psi.elements.StringLiteralExpression;
import de.espend.idea.php.annotation.dict.PhpDocCommentAnnotation;
import de.espend.idea.php.annotation.dict.PhpDocTagAnnotation;
import de.espend.idea.php.annotation.extension.PhpAnnotationReferenceProvider;
import de.espend.idea.php.annotation.extension.parameter.AnnotationPropertyParameter;
import de.espend.idea.php.annotation.extension.parameter.PhpAnnotationReferenceProviderParameter;
import de.espend.idea.php.annotation.util.AnnotationUtil;
import fr.adrienbrault.idea.symfony2plugin.Symfony2ProjectComponent;
import fr.adrienbrault.idea.symfony2plugin.doctrine.dict.DoctrineModelField;
import fr.adrienbrault.idea.symfony2plugin.doctrine.dict.DoctrineModelFieldLookupElement;
import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class DoctrineAnnotationReferencedColumnReferences implements PhpAnnotationReferenceProvider {

    @Nullable
    @Override
    public PsiReference[] getPropertyReferences(AnnotationPropertyParameter annotationPropertyParameter, PhpAnnotationReferenceProviderParameter phpAnnotationReferenceProviderParameter) {

        PsiElement element = annotationPropertyParameter.getElement();
        if(!Symfony2ProjectComponent.isEnabled(annotationPropertyParameter.getProject()) ||
            !(element instanceof StringLiteralExpression) ||
            !PhpElementsUtil.isEqualClassName(annotationPropertyParameter.getPhpClass(), "\\Doctrine\\ORM\\Mapping\\JoinColumn")
            )
        {
            return new PsiReference[0];
        }

        // @Foo(targetEntity="Foo\Class")
        if(annotationPropertyParameter.getType() == AnnotationPropertyParameter.Type.PROPERTY_VALUE && "referencedColumnName".equals(annotationPropertyParameter.getPropertyName())) {

            PhpDocComment phpDocComment = PsiTreeUtil.getParentOfType(element, PhpDocComment.class);
            if(phpDocComment != null) {
                PhpDocCommentAnnotation phpDocCommentAnnotationContainer = AnnotationUtil.getPhpDocCommentAnnotationContainer(phpDocComment);

                if(phpDocCommentAnnotationContainer != null) {

                    PhpDocTagAnnotation phpDocTagAnnotation = phpDocCommentAnnotationContainer.getFirstPhpDocBlock(
                        "\\Doctrine\\ORM\\Mapping\\ManyToOne",
                        "\\Doctrine\\ORM\\Mapping\\ManyToMany",
                        "\\Doctrine\\ORM\\Mapping\\OneToOne",
                        "\\Doctrine\\ORM\\Mapping\\OneToMany"
                    );

                    if(phpDocTagAnnotation != null) {

                        PhpPsiElement phpDocAttrList = phpDocTagAnnotation.getPhpDocTag().getFirstPsiChild();

                        // @TODO: remove nested on Annotation plugin update
                        if(phpDocAttrList != null) {
                            if(phpDocAttrList.getNode().getElementType() == PhpDocElementTypes.phpDocAttributeList) {
                                PhpPsiElement phpPsiElement = phpDocAttrList.getFirstPsiChild();
                                if(phpPsiElement instanceof StringLiteralExpression) {
                                    PhpClass phpClass = de.espend.idea.php.annotation.util.PhpElementsUtil.getClassInsideAnnotation(((StringLiteralExpression) phpPsiElement));
                                    if(phpClass != null) {
                                        List<DoctrineModelField> lists = EntityHelper.getModelFields(phpClass);
                                        if(lists.size() > 0) {
                                            return new PsiReference[] {
                                                new EntityReference((StringLiteralExpression) element, lists)
                                            };
                                        }
                                    }
                                }
                            }
                        }


                    }

                }

            }

        }

        return new PsiReference[0];
    }

    public class EntityReference extends PsiPolyVariantReferenceBase<PsiElement> {

        final private List<DoctrineModelField> doctrineModelField;
        final private String content;

        public EntityReference(StringLiteralExpression psiElement, List<DoctrineModelField> doctrineModelField) {
            super(psiElement);
            this.doctrineModelField = doctrineModelField;
            this.content = psiElement.getContents();
        }

        @NotNull
        @Override
        public ResolveResult[] multiResolve(boolean b) {

            Collection<PsiElement> targets = new ArrayList<PsiElement>();
            for(DoctrineModelField field: doctrineModelField) {
                if(this.content.equals(field.getColumn())) {
                    targets.addAll(field.getTargets());
                }
            }

            return PsiElementResolveResult.createResults(targets);
        }

        @NotNull
        @Override
        public Object[] getVariants() {

            List<LookupElement> lookupElements = new ArrayList<LookupElement>();
            for(DoctrineModelField field: doctrineModelField) {
                String column = field.getColumn();
                if(column != null) {
                    lookupElements.add(new DoctrineModelFieldLookupElement(field).withLookupName(column));
                }
            }

            return lookupElements.toArray();

        }

    }

}
TOP

Related Classes of fr.adrienbrault.idea.symfony2plugin.doctrine.DoctrineAnnotationReferencedColumnReferences

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.