<commit_before>package fr.tolc.jahia.intellij.plugin.cnd.annotators;

import java.io.File;

import com.intellij.lang.annotation.Annotation;
import com.intellij.lang.annotation.AnnotationHolder;
import com.intellij.lang.annotation.Annotator;
import com.intellij.psi.PsiElement;
import fr.tolc.jahia.intellij.plugin.cnd.CndSyntaxHighlighter;
import fr.tolc.jahia.intellij.plugin.cnd.CndTranslationUtil;
import fr.tolc.jahia.intellij.plugin.cnd.CndUtil;
import fr.tolc.jahia.intellij.plugin.cnd.enums.ItemTypeEnum;
import fr.tolc.jahia.intellij.plugin.cnd.enums.PropertyAttributeEnum;
import fr.tolc.jahia.intellij.plugin.cnd.enums.PropertyTypeEnum;
import fr.tolc.jahia.intellij.plugin.cnd.enums.PropertyTypeMaskEnum;
import fr.tolc.jahia.intellij.plugin.cnd.psi.CndTypes;
import fr.tolc.jahia.intellij.plugin.cnd.quickfixes.CreateNodeTypeFilesQuickFix;
import fr.tolc.jahia.intellij.plugin.cnd.quickfixes.CreateNodeTypeTranslationsQuickFix;
import fr.tolc.jahia.intellij.plugin.cnd.quickfixes.CreateNodeTypeViewQuickFix;
import org.jetbrains.annotations.NotNull;

public class CndCndAnnotator implements Annotator {

    @Override
    public void annotate(@NotNull final PsiElement element, @NotNull AnnotationHolder holder) {
        if (element.getNode() != null) {
            if (CndTypes.NODE_TYPE_NAME.equals(element.getNode().getElementType())) {
                String nodeTypeName = element.getText();

                PsiElement nextSibling = element.getNextSibling();
                if (nextSibling != null && CndTypes.RIGHT_BRACKET.equals(nextSibling.getNode().getElementType())) { //Make sure this is a node type declaration, and not use

                    PsiElement colonEl = element.getPrevSibling();
                    if (colonEl != null && CndTypes.COLON.equals(colonEl.getNode().getElementType())) {

                        PsiElement namespaceEl = colonEl.getPrevSibling();
                        if (namespaceEl != null && CndTypes.NAMESPACE_NAME.equals(namespaceEl.getNode().getElementType())) {
                            String namespace = namespaceEl.getText();

//                            Project project = element.getProject();
//                            Module currentModule = ProjectRootManager.getInstance(project).getFileIndex().getModuleForFile(element.getContainingFile().getVirtualFile());
//                            VirtualFile[] sourceRoots = ModuleRootManager.getInstance(currentModule).getSourceRoots();

                            String jahiaWorkFolderPath = CndUtil.getJahiaWorkFolderPath(element);

                            if (jahiaWorkFolderPath != null) {
                                //                            VirtualFile nodeTypeFolder = null;
                                //                            for (VirtualFile sourceRoot : sourceRoots) {
                                //                                nodeTypeFolder = sourceRoot.findFileByRelativePath("main/webapp/" + namespace + "_" + nodeTypeName);
                                //                                if (nodeTypeFolder != null) {
                                //                                    break;
                                //                                }
                                //                            }

                                String nodeTypeFolderPath = CndUtil.getNodeTypeFolderPath(jahiaWorkFolderPath, namespace, nodeTypeName);
                                File nodeTypeFolder = new File(nodeTypeFolderPath);
                                if (!nodeTypeFolder.exists() || !nodeTypeFolder.isDirectory()) {
                                    Annotation annotation = holder.createInfoAnnotation(element.getTextRange(), "Node type " + namespace + ":" + nodeTypeName + " does not have any associated folder");
                                    annotation.setTextAttributes(CndSyntaxHighlighter.NODE_TYPE);
                                    annotation.registerFix(new CreateNodeTypeFilesQuickFix(jahiaWorkFolderPath, namespace, nodeTypeName));
                                } else {
                                    Annotation annotation = holder.createInfoAnnotation(element.getTextRange(), "Create a new view for " + namespace + ":" + nodeTypeName);
                                    annotation.setTextAttributes(CndSyntaxHighlighter.NODE_TYPE);
                                    annotation.registerFix(new CreateNodeTypeViewQuickFix(jahiaWorkFolderPath, namespace, nodeTypeName));
                                }


                                //Translation
                                if (CndTranslationUtil.getNodeTypeTranslation(element.getProject(), namespace, nodeTypeName) == null) {
                                    Annotation annotation = holder.createInfoAnnotation(element.getTextRange(), "Node type " + namespace + ":" + nodeTypeName + "does not have any translation");
                                    annotation.setTextAttributes(CndSyntaxHighlighter.NODE_TYPE);
                                    annotation.registerFix(new CreateNodeTypeTranslationsQuickFix(jahiaWorkFolderPath, namespace, nodeTypeName));
                                }

                            }
                        }
                    }
                }
            }

            //Property type
            if (CndTypes.PROPERTY_TYPE.equals(element.getNode().getElementType())) {
                try {
                    PropertyTypeEnum.fromValue(element.getText());
                } catch (IllegalArgumentException e) {
                    holder.createErrorAnnotation(element.getTextRange(), "Invalid property type");
                }
            }

            //Property mask
            if (CndTypes.PROPERTY_MASK.equals(element.getNode().getElementType())) {
                try {
                    PropertyTypeMaskEnum.fromValue(element.getText());
                } catch (IllegalArgumentException e) {
                    holder.createErrorAnnotation(element.getTextRange(), "Invalid property type mask");
                }
            }

            //Property attribute
            if (CndTypes.PROPERTY_ATTRIBUTE.equals(element.getNode().getElementType())) {
                try {
                    PropertyAttributeEnum.fromValue(element.getText());
                } catch (IllegalArgumentException e) {
                    holder.createErrorAnnotation(element.getTextRange(), "Invalid property attribute");
//                    Annotation annotation = holder.createErrorAnnotation(element.getTextRange(), "Invalid property attribute");
//                    annotation.registerFix(new ChangeToClosestQuickFix(element, CndConstants.PROPERTY_ATTRIBUTES));
                }
            }

            //Item type
            if (CndTypes.ITEMTYPE_TYPE.equals(element.getNode().getElementType())) {
                try {
                    ItemTypeEnum.fromValue(element.getText());
                } catch (IllegalArgumentException e) {
                    holder.createErrorAnnotation(element.getTextRange(), "Invalid item type");
                }
            }
        }
    }
}
<commit_msg>Annotations added for invalid node type uses in Cnd file<commit_after>package fr.tolc.jahia.intellij.plugin.cnd.annotators;

import java.io.File;

import com.intellij.lang.annotation.Annotation;
import com.intellij.lang.annotation.AnnotationHolder;
import com.intellij.lang.annotation.Annotator;
import com.intellij.psi.PsiElement;
import fr.tolc.jahia.intellij.plugin.cnd.CndSyntaxHighlighter;
import fr.tolc.jahia.intellij.plugin.cnd.CndTranslationUtil;
import fr.tolc.jahia.intellij.plugin.cnd.CndUtil;
import fr.tolc.jahia.intellij.plugin.cnd.enums.ItemTypeEnum;
import fr.tolc.jahia.intellij.plugin.cnd.enums.PropertyAttributeEnum;
import fr.tolc.jahia.intellij.plugin.cnd.enums.PropertyTypeEnum;
import fr.tolc.jahia.intellij.plugin.cnd.enums.PropertyTypeMaskEnum;
import fr.tolc.jahia.intellij.plugin.cnd.psi.CndNamespace;
import fr.tolc.jahia.intellij.plugin.cnd.psi.CndNodeType;
import fr.tolc.jahia.intellij.plugin.cnd.psi.CndTypes;
import fr.tolc.jahia.intellij.plugin.cnd.quickfixes.CreateNodeTypeFilesQuickFix;
import fr.tolc.jahia.intellij.plugin.cnd.quickfixes.CreateNodeTypeTranslationsQuickFix;
import fr.tolc.jahia.intellij.plugin.cnd.quickfixes.CreateNodeTypeViewQuickFix;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.NotNull;

public class CndCndAnnotator implements Annotator {

    @Override
    public void annotate(@NotNull final PsiElement element, @NotNull AnnotationHolder holder) {
        if (element.getNode() != null) {
            //Node type declaration
            if (CndTypes.NODE_TYPE_NAME.equals(element.getNode().getElementType())) {
                String nodeTypeName = element.getText();

                PsiElement nextSibling = element.getNextSibling();
                if (nextSibling != null && CndTypes.RIGHT_BRACKET.equals(nextSibling.getNode().getElementType())) { //Make sure this is a node type declaration, and not use

                    PsiElement colonEl = element.getPrevSibling();
                    if (colonEl != null && CndTypes.COLON.equals(colonEl.getNode().getElementType())) {

                        PsiElement namespaceEl = colonEl.getPrevSibling();
                        if (namespaceEl != null && CndTypes.NAMESPACE_NAME.equals(namespaceEl.getNode().getElementType())) {
                            String namespace = namespaceEl.getText();

//                            Project project = element.getProject();
//                            Module currentModule = ProjectRootManager.getInstance(project).getFileIndex().getModuleForFile(element.getContainingFile().getVirtualFile());
//                            VirtualFile[] sourceRoots = ModuleRootManager.getInstance(currentModule).getSourceRoots();

                            //TODO: check for namespace existence
                            
                            String jahiaWorkFolderPath = CndUtil.getJahiaWorkFolderPath(element);

                            if (jahiaWorkFolderPath != null) {
                                //                            VirtualFile nodeTypeFolder = null;
                                //                            for (VirtualFile sourceRoot : sourceRoots) {
                                //                                nodeTypeFolder = sourceRoot.findFileByRelativePath("main/webapp/" + namespace + "_" + nodeTypeName);
                                //                                if (nodeTypeFolder != null) {
                                //                                    break;
                                //                                }
                                //                            }

                                String nodeTypeFolderPath = CndUtil.getNodeTypeFolderPath(jahiaWorkFolderPath, namespace, nodeTypeName);
                                File nodeTypeFolder = new File(nodeTypeFolderPath);
                                if (!nodeTypeFolder.exists() || !nodeTypeFolder.isDirectory()) {
                                    Annotation annotation = holder.createInfoAnnotation(element.getTextRange(), "Node type " + namespace + ":" + nodeTypeName + " does not have any associated folder");
                                    annotation.setTextAttributes(CndSyntaxHighlighter.NODE_TYPE);
                                    annotation.registerFix(new CreateNodeTypeFilesQuickFix(jahiaWorkFolderPath, namespace, nodeTypeName));
                                } else {
                                    Annotation annotation = holder.createInfoAnnotation(element.getTextRange(), "Create a new view for " + namespace + ":" + nodeTypeName);
                                    annotation.setTextAttributes(CndSyntaxHighlighter.NODE_TYPE);
                                    annotation.registerFix(new CreateNodeTypeViewQuickFix(jahiaWorkFolderPath, namespace, nodeTypeName));
                                }


                                //Translation
                                if (CndTranslationUtil.getNodeTypeTranslation(element.getProject(), namespace, nodeTypeName) == null) {
                                    Annotation annotation = holder.createInfoAnnotation(element.getTextRange(), "Node type " + namespace + ":" + nodeTypeName + "does not have any translation");
                                    annotation.setTextAttributes(CndSyntaxHighlighter.NODE_TYPE);
                                    annotation.registerFix(new CreateNodeTypeTranslationsQuickFix(jahiaWorkFolderPath, namespace, nodeTypeName));
                                }

                            }
                        }
                    }
                }
            }

            //Property type
            else if (CndTypes.PROPERTY_TYPE.equals(element.getNode().getElementType())) {
                try {
                    PropertyTypeEnum.fromValue(element.getText());
                } catch (IllegalArgumentException e) {
                    holder.createErrorAnnotation(element.getTextRange(), "Invalid property type");
                }
            }

            //Property mask
            else if (CndTypes.PROPERTY_MASK.equals(element.getNode().getElementType())) {
                try {
                    PropertyTypeMaskEnum.fromValue(element.getText());
                } catch (IllegalArgumentException e) {
                    holder.createErrorAnnotation(element.getTextRange(), "Invalid property type mask");
                }
            }

            //Property attribute
            else if (CndTypes.PROPERTY_ATTRIBUTE.equals(element.getNode().getElementType())) {
                try {
                    PropertyAttributeEnum.fromValue(element.getText());
                } catch (IllegalArgumentException e) {
                    holder.createErrorAnnotation(element.getTextRange(), "Invalid property attribute");
//                    Annotation annotation = holder.createErrorAnnotation(element.getTextRange(), "Invalid property attribute");
//                    annotation.registerFix(new ChangeToClosestQuickFix(element, CndConstants.PROPERTY_ATTRIBUTES));
                }
            }

            //Item type
            else if (CndTypes.ITEMTYPE_TYPE.equals(element.getNode().getElementType())) {
                try {
                    ItemTypeEnum.fromValue(element.getText());
                } catch (IllegalArgumentException e) {
                    holder.createErrorAnnotation(element.getTextRange(), "Invalid item type");
                }
            }
            
            //Check for invalid namespaces and nodetypes
            else if (CndTypes.SUPER_TYPE.equals(element.getNode().getElementType())
                || CndTypes.EXTENSION.equals(element.getNode().getElementType())
                || CndTypes.SUB_NODE_TYPE.equals(element.getNode().getElementType())
                || CndTypes.SUB_NODE_DEFAULT_TYPE.equals(element.getNode().getElementType())) {

                PsiElement namespaceElt = element.getFirstChild();
                if (namespaceElt != null) {
                    CndNamespace cndNamespace = CndUtil.findNamespace(element.getProject(), namespaceElt.getText());
                    if (cndNamespace == null) {
                        holder.createErrorAnnotation(namespaceElt.getTextRange(), "Unresolved CND namespace");
                    } else {
                        PsiElement colonElt = namespaceElt.getNextSibling();
                        if (colonElt == null) {
                            holder.createErrorAnnotation(element.getTextRange(), "Invalid CND node type (mising colon)");
                        } else {
                            PsiElement nodeTypeElt = colonElt.getNextSibling();
                            if (nodeTypeElt == null || StringUtils.isBlank(nodeTypeElt.getText())) {
                                holder.createErrorAnnotation(element.getTextRange(), "Invalid CND node type (missing node type name)"); 
                            } else if (!"jnt".equals(namespaceElt.getText()) && !"jmix".equals(namespaceElt.getText()) && !"mix".equals(namespaceElt.getText())) {
                                //TODO: change or remove this condition after embedding Jahia default and modules cnd files  
                                CndNodeType cndNodeType = CndUtil.findNodeType(element.getProject(), namespaceElt.getText(), nodeTypeElt.getText());
                                if (cndNodeType == null) {
                                    holder.createErrorAnnotation(nodeTypeElt.getTextRange(), "Unresolved CND node type");
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

{'fraction_non_alphanumeric': 0.09104929117978527, 'fraction_numerical': 0.0, 'mean_word_length': 1.729922279792746, 'pattern_counts': {'":': 6, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 54, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6001092', 'n_tokens_mistral': 4106, 'n_tokens_neox': 3899, 'n_words': 629}