From 3d9989e0c5709cd6cbbe38dd2515897ce3f375f0 Mon Sep 17 00:00:00 2001 From: bohdan-harniuk Date: Fri, 23 Oct 2020 16:13:54 +0300 Subject: [PATCH 1/4] Added index, completion and references for table names, column names in db_schema.xml file --- resources/META-INF/plugin.xml | 1 + .../ColumnNameCompletionProvider.java | 115 +++++++++++ .../provider/TableNameCompletionProvider.java | 46 +++++ .../xml/XmlCompletionContributor.java | 58 ++++++ .../magento2plugin/indexes/IndexManager.java | 2 + .../magento/files/ModuleDbSchemaXml.java | 47 +++++ .../TableColumnNamesReferenceProvider.java | 190 ++++++++++++++++++ .../xml/XmlReferenceContributor.java | 69 +++++++ .../indexes/xml/TableAndColumnNameIndex.java | 93 +++++++++ .../db_schema.xml | 13 ++ .../db_schema.xml | 13 ++ .../db_schema.xml | 13 ++ .../db_schema.xml | 13 ++ .../tableNameMustHaveCompletion/db_schema.xml | 11 + .../magento/module-catalog/etc/db_schema.xml | 63 ++++++ .../db_schema.xml | 13 ++ .../db_schema.xml | 13 ++ .../db_schema.xml | 13 ++ .../db_schema.xml | 13 ++ .../tableTagMustHaveReference/db_schema.xml | 11 + ...eAndColumnNameCompletionRegistrarTest.java | 60 ++++++ .../reference/BaseReferenceTestCase.java | 88 ++++---- ...leNameAndColumnReferenceRegistrarTest.java | 69 +++++++ 23 files changed, 977 insertions(+), 50 deletions(-) create mode 100644 src/com/magento/idea/magento2plugin/completion/provider/ColumnNameCompletionProvider.java create mode 100644 src/com/magento/idea/magento2plugin/completion/provider/TableNameCompletionProvider.java create mode 100644 src/com/magento/idea/magento2plugin/magento/files/ModuleDbSchemaXml.java create mode 100644 src/com/magento/idea/magento2plugin/reference/provider/TableColumnNamesReferenceProvider.java create mode 100644 src/com/magento/idea/magento2plugin/stubs/indexes/xml/TableAndColumnNameIndex.java create mode 100644 testData/completion/xml/TableAndColumnNameCompletionRegistrar/constraintColumnNameMustHaveCompletion/db_schema.xml create mode 100644 testData/completion/xml/TableAndColumnNameCompletionRegistrar/constraintReferenceColumnNameMustHaveCompletion/db_schema.xml create mode 100644 testData/completion/xml/TableAndColumnNameCompletionRegistrar/constraintTagReferenceTableMustHaveCompletion/db_schema.xml create mode 100644 testData/completion/xml/TableAndColumnNameCompletionRegistrar/constraintTagTableMustHaveCompletion/db_schema.xml create mode 100644 testData/completion/xml/TableAndColumnNameCompletionRegistrar/tableNameMustHaveCompletion/db_schema.xml create mode 100644 testData/project/magento2/vendor/magento/module-catalog/etc/db_schema.xml create mode 100644 testData/reference/xml/TableNameAndColumnReferenceRegistrar/constraintColumnTagMustHaveReference/db_schema.xml create mode 100644 testData/reference/xml/TableNameAndColumnReferenceRegistrar/constraintReferenceColumnTagMustHaveReference/db_schema.xml create mode 100644 testData/reference/xml/TableNameAndColumnReferenceRegistrar/constraintReferenceTableTagMustHaveReference/db_schema.xml create mode 100644 testData/reference/xml/TableNameAndColumnReferenceRegistrar/constraintTableTagMustHaveReference/db_schema.xml create mode 100644 testData/reference/xml/TableNameAndColumnReferenceRegistrar/tableTagMustHaveReference/db_schema.xml create mode 100644 tests/com/magento/idea/magento2plugin/completion/xml/TableAndColumnNameCompletionRegistrarTest.java create mode 100644 tests/com/magento/idea/magento2plugin/reference/xml/TableNameAndColumnReferenceRegistrarTest.java diff --git a/resources/META-INF/plugin.xml b/resources/META-INF/plugin.xml index 8af540006..b93bff8b0 100644 --- a/resources/META-INF/plugin.xml +++ b/resources/META-INF/plugin.xml @@ -126,6 +126,7 @@ + diff --git a/src/com/magento/idea/magento2plugin/completion/provider/ColumnNameCompletionProvider.java b/src/com/magento/idea/magento2plugin/completion/provider/ColumnNameCompletionProvider.java new file mode 100644 index 000000000..04039759a --- /dev/null +++ b/src/com/magento/idea/magento2plugin/completion/provider/ColumnNameCompletionProvider.java @@ -0,0 +1,115 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.completion.provider; + +import com.intellij.codeInsight.completion.CompletionParameters; +import com.intellij.codeInsight.completion.CompletionProvider; +import com.intellij.codeInsight.completion.CompletionResultSet; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.psi.PsiElement; +import com.intellij.psi.impl.source.xml.XmlAttributeImpl; +import com.intellij.psi.impl.source.xml.XmlTagImpl; +import com.intellij.psi.xml.XmlTag; +import com.intellij.util.ProcessingContext; +import com.intellij.util.indexing.FileBasedIndex; +import com.magento.idea.magento2plugin.magento.files.ModuleDbSchemaXml; +import com.magento.idea.magento2plugin.stubs.indexes.xml.TableAndColumnNameIndex; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; +import org.jetbrains.annotations.NotNull; + +/** + * Provides column names for completion. + */ +public class ColumnNameCompletionProvider extends CompletionProvider { + @Override + protected void addCompletions( + final @NotNull CompletionParameters parameters, + final @NotNull ProcessingContext context, + final @NotNull CompletionResultSet result + ) { + final PsiElement position = parameters.getPosition().getOriginalElement(); + final String currentAttrName = getCurrentAttributeName(position); + if (position == null || currentAttrName == null) { + return; + } + String targetTableAttrName; + + switch (currentAttrName) { + case ModuleDbSchemaXml.XML_ATTR_CONSTRAINT_COLUMN_NAME: + targetTableAttrName = ModuleDbSchemaXml.XML_ATTR_CONSTRAINT_TABLE_NAME; + break; + case ModuleDbSchemaXml.XML_ATTR_CONSTRAINT_REFERENCE_COLUMN_NAME: + targetTableAttrName = ModuleDbSchemaXml.XML_ATTR_CONSTRAINT_REFERENCE_TABLE_NAME; + break; + default: + return; + } + final String targetTableName = getTargetTableFromPositionAndAttrName( + position, + targetTableAttrName + ); + + if (targetTableName == null) { + return; + } + final Collection tableAndColumnNames = FileBasedIndex.getInstance().getAllKeys( + TableAndColumnNameIndex.KEY, position.getProject() + ); + final List filteredColumnNames = tableAndColumnNames.stream() + .filter(name -> name.contains(targetTableName + ".")).collect(Collectors.toList()) + .stream().map(name -> name.substring(name.indexOf(".") + 1)) + .collect(Collectors.toList()); + + for (final String columnName: filteredColumnNames) { + result.addElement(LookupElementBuilder.create(columnName)); + } + } + + /** + * Get attribute name from position. + * + * @param position PsiElement + * + * @return String + */ + private String getCurrentAttributeName(final PsiElement position) { + if (position instanceof XmlAttributeImpl) { + return ((XmlAttributeImpl) position).getName(); + } else { + return getCurrentAttributeName(position.getParent()); + } + } + + /** + * Get reference table name from current position. + * + * @param position PsiElement + * @param targetTableAttrName String + * + * @return String + */ + private String getTargetTableFromPositionAndAttrName( + final PsiElement position, + final String targetTableAttrName + ) { + if (targetTableAttrName == null) { + return null; + } + + if (position instanceof XmlTagImpl + && ((XmlTag) position).getName().equals(ModuleDbSchemaXml.XML_TAG_CONSTRAINT)) { + return ((XmlTag) position) + .getAttributeValue(targetTableAttrName); + } else { + return getTargetTableFromPositionAndAttrName( + position.getParent(), + targetTableAttrName + ); + } + } +} diff --git a/src/com/magento/idea/magento2plugin/completion/provider/TableNameCompletionProvider.java b/src/com/magento/idea/magento2plugin/completion/provider/TableNameCompletionProvider.java new file mode 100644 index 000000000..1a4f625f4 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/completion/provider/TableNameCompletionProvider.java @@ -0,0 +1,46 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.completion.provider; + +import com.intellij.codeInsight.completion.CompletionParameters; +import com.intellij.codeInsight.completion.CompletionProvider; +import com.intellij.codeInsight.completion.CompletionResultSet; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.psi.PsiElement; +import com.intellij.util.ProcessingContext; +import com.intellij.util.indexing.FileBasedIndex; +import com.magento.idea.magento2plugin.stubs.indexes.xml.TableAndColumnNameIndex; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; +import org.jetbrains.annotations.NotNull; + +/** + * Provides table names for completion. + */ +public class TableNameCompletionProvider extends CompletionProvider { + @Override + protected void addCompletions( + final @NotNull CompletionParameters parameters, + final @NotNull ProcessingContext context, + final @NotNull CompletionResultSet result + ) { + final PsiElement position = parameters.getPosition().getOriginalElement(); + if (position == null) { + return; + } + + final Collection tableNames = FileBasedIndex.getInstance().getAllKeys( + TableAndColumnNameIndex.KEY, position.getProject() + ); + final List filteredTableNames = tableNames.stream() + .filter(name -> !name.contains(".")).collect(Collectors.toList()); + + for (final String tableName: filteredTableNames) { + result.addElement(LookupElementBuilder.create(tableName)); + } + } +} diff --git a/src/com/magento/idea/magento2plugin/completion/xml/XmlCompletionContributor.java b/src/com/magento/idea/magento2plugin/completion/xml/XmlCompletionContributor.java index cc2e5e651..35b36b297 100644 --- a/src/com/magento/idea/magento2plugin/completion/xml/XmlCompletionContributor.java +++ b/src/com/magento/idea/magento2plugin/completion/xml/XmlCompletionContributor.java @@ -324,6 +324,64 @@ public XmlCompletionContributor() { new MenuCompletionProvider() ); + // in db_schema.xml + extend(CompletionType.BASIC, psiElement(XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN) + .inside(XmlPatterns.xmlAttribute().withName(ModuleDbSchemaXml.XML_ATTR_TABLE_NAME) + .withParent(XmlPatterns.xmlTag().withName(ModuleDbSchemaXml.XML_TAG_TABLE) + .withParent(XmlPatterns.xmlTag() + .withName(ModuleDbSchemaXml.XML_TAG_SCHEMA)))) + .inFile(xmlFile().withName(string().matches(ModuleDbSchemaXml.FILE_NAME))), + new TableNameCompletionProvider() + ); + + // in db_schema.xml + extend(CompletionType.BASIC, psiElement(XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN) + .inside(XmlPatterns.xmlAttribute() + .withName(ModuleDbSchemaXml.XML_ATTR_CONSTRAINT_TABLE_NAME) + .withParent(XmlPatterns.xmlTag() + .withName(ModuleDbSchemaXml.XML_TAG_CONSTRAINT) + .withParent(XmlPatterns.xmlTag() + .withName(ModuleDbSchemaXml.XML_TAG_TABLE)))) + .inFile(xmlFile().withName(string().matches(ModuleDbSchemaXml.FILE_NAME))), + new TableNameCompletionProvider() + ); + + // in db_schema.xml + extend(CompletionType.BASIC, psiElement(XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN) + .inside(XmlPatterns.xmlAttribute() + .withName(ModuleDbSchemaXml.XML_ATTR_CONSTRAINT_REFERENCE_TABLE_NAME) + .withParent(XmlPatterns.xmlTag() + .withName(ModuleDbSchemaXml.XML_TAG_CONSTRAINT) + .withParent(XmlPatterns.xmlTag() + .withName(ModuleDbSchemaXml.XML_TAG_TABLE)))) + .inFile(xmlFile().withName(string().matches(ModuleDbSchemaXml.FILE_NAME))), + new TableNameCompletionProvider() + ); + + // in db_schema.xml + extend(CompletionType.BASIC, psiElement(XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN) + .inside(XmlPatterns.xmlAttribute() + .withName(ModuleDbSchemaXml.XML_ATTR_CONSTRAINT_COLUMN_NAME) + .withParent(XmlPatterns.xmlTag() + .withName(ModuleDbSchemaXml.XML_TAG_CONSTRAINT) + .withParent(XmlPatterns.xmlTag() + .withName(ModuleDbSchemaXml.XML_TAG_TABLE)))) + .inFile(xmlFile().withName(string().matches(ModuleDbSchemaXml.FILE_NAME))), + new ColumnNameCompletionProvider() + ); + + // in db_schema.xml + extend(CompletionType.BASIC, psiElement(XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN) + .inside(XmlPatterns.xmlAttribute() + .withName(ModuleDbSchemaXml.XML_ATTR_CONSTRAINT_REFERENCE_COLUMN_NAME) + .withParent(XmlPatterns.xmlTag() + .withName(ModuleDbSchemaXml.XML_TAG_CONSTRAINT) + .withParent(XmlPatterns.xmlTag() + .withName(ModuleDbSchemaXml.XML_TAG_TABLE)))) + .inFile(xmlFile().withName(string().matches(ModuleDbSchemaXml.FILE_NAME))), + new ColumnNameCompletionProvider() + ); + registerCompletionsForDifferentNesting(); } diff --git a/src/com/magento/idea/magento2plugin/indexes/IndexManager.java b/src/com/magento/idea/magento2plugin/indexes/IndexManager.java index 6eb7dd450..da161418d 100644 --- a/src/com/magento/idea/magento2plugin/indexes/IndexManager.java +++ b/src/com/magento/idea/magento2plugin/indexes/IndexManager.java @@ -27,6 +27,7 @@ import com.magento.idea.magento2plugin.stubs.indexes.xml.AclResourceIndex; import com.magento.idea.magento2plugin.stubs.indexes.xml.MenuIndex; import com.magento.idea.magento2plugin.stubs.indexes.xml.PhpClassNameIndex; +import com.magento.idea.magento2plugin.stubs.indexes.xml.TableAndColumnNameIndex; import com.magento.idea.magento2plugin.stubs.indexes.xml.UIComponentIndex; @SuppressWarnings({"PMD.ClassNamingConventions", "PMD.UseUtilityClass"}) @@ -42,6 +43,7 @@ public static void manualReindex() { // xml|di configuration PluginIndex.KEY, VirtualTypeIndex.KEY, + TableAndColumnNameIndex.KEY, // layouts BlockNameIndex.KEY, ContainerNameIndex.KEY, diff --git a/src/com/magento/idea/magento2plugin/magento/files/ModuleDbSchemaXml.java b/src/com/magento/idea/magento2plugin/magento/files/ModuleDbSchemaXml.java new file mode 100644 index 000000000..8c2a68ff2 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/magento/files/ModuleDbSchemaXml.java @@ -0,0 +1,47 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.magento.files; + +import com.intellij.lang.Language; +import com.intellij.lang.xml.XMLLanguage; + +public class ModuleDbSchemaXml implements ModuleFileInterface { + private static final ModuleDbSchemaXml INSTANCE = new ModuleDbSchemaXml(); + public static final String FILE_NAME = "db_schema.xml"; + public static final String TEMPLATE = "Magento Module Declarative Schema XML"; + + //attributes + public static final String XML_ATTR_TABLE_NAME = "name"; + public static final String XML_ATTR_COLUMN_NAME = "name"; + public static final String XML_ATTR_CONSTRAINT_TABLE_NAME = "table"; + public static final String XML_ATTR_CONSTRAINT_REFERENCE_TABLE_NAME = "referenceTable"; + public static final String XML_ATTR_CONSTRAINT_COLUMN_NAME = "column"; + public static final String XML_ATTR_CONSTRAINT_REFERENCE_COLUMN_NAME = "referenceColumn"; + //tags + public static final String XML_TAG_SCHEMA = "schema"; + public static final String XML_TAG_TABLE = "table"; + public static final String XML_TAG_COLUMN = "column"; + public static final String XML_TAG_CONSTRAINT = "constraint"; + + public static ModuleDbSchemaXml getInstance() { + return INSTANCE; + } + + @Override + public String getFileName() { + return FILE_NAME; + } + + @Override + public String getTemplate() { + return TEMPLATE; + } + + @Override + public Language getLanguage() { + return XMLLanguage.INSTANCE; + } +} diff --git a/src/com/magento/idea/magento2plugin/reference/provider/TableColumnNamesReferenceProvider.java b/src/com/magento/idea/magento2plugin/reference/provider/TableColumnNamesReferenceProvider.java new file mode 100644 index 000000000..81d74fcf1 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/reference/provider/TableColumnNamesReferenceProvider.java @@ -0,0 +1,190 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.reference.provider; + +import com.intellij.ide.highlighter.XmlFileType; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiReference; +import com.intellij.psi.PsiReferenceProvider; +import com.intellij.psi.impl.source.xml.XmlAttributeImpl; +import com.intellij.psi.impl.source.xml.XmlAttributeValueImpl; +import com.intellij.psi.impl.source.xml.XmlTagImpl; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.xml.XmlAttribute; +import com.intellij.psi.xml.XmlDocument; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.xml.XmlTag; +import com.intellij.util.ProcessingContext; +import com.intellij.util.indexing.FileBasedIndex; +import com.magento.idea.magento2plugin.magento.files.ModuleDbSchemaXml; +import com.magento.idea.magento2plugin.reference.xml.PolyVariantReferenceBase; +import com.magento.idea.magento2plugin.stubs.indexes.xml.TableAndColumnNameIndex; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import org.jetbrains.annotations.NotNull; + + +/** + * Reference provider for table and column names in the db_schema.xml files. + */ +public class TableColumnNamesReferenceProvider extends PsiReferenceProvider { + @NotNull + @Override + @SuppressWarnings({"PMD.NPathComplexity", "PMD.CyclomaticComplexity", + "PMD.AvoidDeeplyNestedIfStmts"}) + public PsiReference[] getReferencesByElement( + final @NotNull PsiElement element, + final @NotNull ProcessingContext context + ) { + final List psiReferences = new ArrayList<>(); + String identifier = ((XmlAttributeValueImpl) element).getValue(); + String columnIdentifier = null; + String tableNameIdentifier = null; + + final String parentTag = getParentTagName(element); + if (parentTag != null && parentTag.equals(ModuleDbSchemaXml.XML_TAG_CONSTRAINT)) { + final XmlAttribute attribute = getParentAttribute(element); + final String attributeName = attribute.getName(); + + if (attributeName.equals(ModuleDbSchemaXml.XML_ATTR_CONSTRAINT_COLUMN_NAME)) { + columnIdentifier = identifier; + tableNameIdentifier = getNearAttributeValueForElement( + attribute, + ModuleDbSchemaXml.XML_TAG_CONSTRAINT, + ModuleDbSchemaXml.XML_ATTR_CONSTRAINT_TABLE_NAME + ); + + if (tableNameIdentifier != null) { + identifier = tableNameIdentifier + "." + columnIdentifier; + } + } + if (attributeName.equals( + ModuleDbSchemaXml.XML_ATTR_CONSTRAINT_REFERENCE_COLUMN_NAME)) { + columnIdentifier = identifier; + tableNameIdentifier = getNearAttributeValueForElement( + attribute, + ModuleDbSchemaXml.XML_TAG_CONSTRAINT, + ModuleDbSchemaXml.XML_ATTR_CONSTRAINT_REFERENCE_TABLE_NAME + ); + + if (tableNameIdentifier != null) { + identifier = tableNameIdentifier + "." + columnIdentifier; + } + } + } + final Collection files = FileBasedIndex.getInstance() + .getContainingFiles(TableAndColumnNameIndex.KEY, identifier, + GlobalSearchScope.getScopeRestrictedByFileTypes( + GlobalSearchScope.allScope(element.getProject()), + XmlFileType.INSTANCE + ) + ); + + final List psiElements = new ArrayList<>(); + final PsiManager psiManager = PsiManager.getInstance(element.getProject()); + + for (final VirtualFile virtualFile : files) { + final XmlDocument xmlDocument = ((XmlFile) Objects.requireNonNull( + psiManager.findFile(virtualFile)) + ).getDocument(); + + if (xmlDocument != null) { + final XmlTag xmlRootTag = xmlDocument.getRootTag(); + + if (xmlRootTag != null) { + final XmlTag[] tableTags = xmlRootTag.getSubTags(); + for (final XmlTag tableTag : tableTags) { + final String tableName = + tableTag.getAttributeValue(ModuleDbSchemaXml.XML_ATTR_TABLE_NAME); + if (tableTag.getName().equals(ModuleDbSchemaXml.XML_TAG_TABLE) + && tableName != null + && tableName.equals(identifier) + && columnIdentifier == null + ) { + psiElements.add(tableTag); + } + + if (tableName != null && tableName.equals(tableNameIdentifier)) { + final XmlTag[] columnTags = tableTag + .findSubTags(ModuleDbSchemaXml.XML_TAG_COLUMN); + for (final XmlTag columnTag : columnTags) { + final String columnName = + columnTag.getAttributeValue( + ModuleDbSchemaXml.XML_ATTR_COLUMN_NAME + ); + if (columnName != null + && columnName.equals(columnIdentifier)) { + psiElements.add(columnTag); + } + } + } + } + } + } + } + + if (!psiElements.isEmpty()) { + psiReferences.add(new PolyVariantReferenceBase(element, psiElements)); + } + + return psiReferences.toArray(new PsiReference[0]); + } + + /** + * Get parent tag of element. + * + * @param element PsiElement + * + * @return String + */ + private String getParentTagName(final PsiElement element) { + if (element instanceof XmlTagImpl) { + return ((XmlTagImpl) element).getName(); + } else { + return getParentTagName(element.getParent()); + } + } + + /** + * Get parent attribute from element. + * + * @param element PsiElement + * + * @return XmlAttribute + */ + private XmlAttribute getParentAttribute(final PsiElement element) { + if (element instanceof XmlAttributeImpl) { + return (XmlAttribute) element; + } else { + return getParentAttribute(element.getParent()); + } + } + + /** + * Get near attribute value. + * + * @param element XmlAttribute + * @param parentTagName String + * @param targetAttributeName String + * + * @return String + */ + private String getNearAttributeValueForElement( + final XmlAttribute element, + final String parentTagName, + final String targetAttributeName + ) { + final XmlTag parentTag = element.getParent(); + if (parentTag.getName().equals(parentTagName)) { + return parentTag.getAttributeValue(targetAttributeName); + } + return null; + } +} diff --git a/src/com/magento/idea/magento2plugin/reference/xml/XmlReferenceContributor.java b/src/com/magento/idea/magento2plugin/reference/xml/XmlReferenceContributor.java index c29142ca4..1d7248be5 100644 --- a/src/com/magento/idea/magento2plugin/reference/xml/XmlReferenceContributor.java +++ b/src/com/magento/idea/magento2plugin/reference/xml/XmlReferenceContributor.java @@ -11,6 +11,7 @@ import com.intellij.psi.xml.XmlTokenType; import com.magento.idea.magento2plugin.magento.files.MftfActionGroup; import com.magento.idea.magento2plugin.magento.files.MftfTest; +import com.magento.idea.magento2plugin.magento.files.ModuleDbSchemaXml; import com.magento.idea.magento2plugin.magento.files.ModuleMenuXml; import com.magento.idea.magento2plugin.magento.files.UiComponentXml; // CHECKSTYLE IGNORE check FOR NEXT 5 LINES @@ -300,6 +301,74 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) new MenuReferenceProvider() ); + //
in db_schema.xml + registrar.registerReferenceProvider( + XmlPatterns.xmlAttributeValue().withParent( + XmlPatterns.xmlAttribute().withName(ModuleDbSchemaXml.XML_ATTR_TABLE_NAME) + .withParent(XmlPatterns.xmlTag().withName(ModuleDbSchemaXml.XML_TAG_TABLE) + ) + ).inFile( + xmlFile().withName(string().matches(ModuleDbSchemaXml.FILE_NAME)) + ), + new TableColumnNamesReferenceProvider() + ); + + // in db_schema.xml + registrar.registerReferenceProvider( + XmlPatterns.xmlAttributeValue().withParent( + XmlPatterns.xmlAttribute() + .withName(ModuleDbSchemaXml.XML_ATTR_CONSTRAINT_TABLE_NAME) + .withParent(XmlPatterns.xmlTag().withName( + ModuleDbSchemaXml.XML_TAG_CONSTRAINT) + ) + ).inFile( + xmlFile().withName(string().matches(ModuleDbSchemaXml.FILE_NAME)) + ), + new TableColumnNamesReferenceProvider() + ); + + // in db_schema.xml + registrar.registerReferenceProvider( + XmlPatterns.xmlAttributeValue().withParent( + XmlPatterns.xmlAttribute() + .withName(ModuleDbSchemaXml.XML_ATTR_CONSTRAINT_REFERENCE_TABLE_NAME) + .withParent(XmlPatterns.xmlTag().withName( + ModuleDbSchemaXml.XML_TAG_CONSTRAINT) + ) + ).inFile( + xmlFile().withName(string().matches(ModuleDbSchemaXml.FILE_NAME)) + ), + new TableColumnNamesReferenceProvider() + ); + + // in db_schema.xml + registrar.registerReferenceProvider( + XmlPatterns.xmlAttributeValue().withParent( + XmlPatterns.xmlAttribute() + .withName(ModuleDbSchemaXml.XML_ATTR_CONSTRAINT_COLUMN_NAME) + .withParent(XmlPatterns.xmlTag().withName( + ModuleDbSchemaXml.XML_TAG_CONSTRAINT) + ) + ).inFile( + xmlFile().withName(string().matches(ModuleDbSchemaXml.FILE_NAME)) + ), + new TableColumnNamesReferenceProvider() + ); + + // in db_schema.xml + registrar.registerReferenceProvider( + XmlPatterns.xmlAttributeValue().withParent( + XmlPatterns.xmlAttribute() + .withName(ModuleDbSchemaXml.XML_ATTR_CONSTRAINT_REFERENCE_COLUMN_NAME) + .withParent(XmlPatterns.xmlTag().withName( + ModuleDbSchemaXml.XML_TAG_CONSTRAINT) + ) + ).inFile( + xmlFile().withName(string().matches(ModuleDbSchemaXml.FILE_NAME)) + ), + new TableColumnNamesReferenceProvider() + ); + registerReferenceForDifferentNesting(registrar); } diff --git a/src/com/magento/idea/magento2plugin/stubs/indexes/xml/TableAndColumnNameIndex.java b/src/com/magento/idea/magento2plugin/stubs/indexes/xml/TableAndColumnNameIndex.java new file mode 100644 index 000000000..51396e0b1 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/stubs/indexes/xml/TableAndColumnNameIndex.java @@ -0,0 +1,93 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.stubs.indexes.xml; + +import com.intellij.ide.highlighter.XmlFileType; +import com.intellij.psi.PsiFile; +import com.intellij.psi.xml.XmlDocument; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.xml.XmlTag; +import com.intellij.util.indexing.DataIndexer; +import com.intellij.util.indexing.FileBasedIndex; +import com.intellij.util.indexing.FileBasedIndexExtension; +import com.intellij.util.indexing.FileContent; +import com.intellij.util.indexing.ID; +import com.intellij.util.io.DataExternalizer; +import com.intellij.util.io.EnumeratorStringDescriptor; +import com.intellij.util.io.KeyDescriptor; +import com.intellij.util.io.VoidDataExternalizer; +import com.magento.idea.magento2plugin.project.Settings; +import java.util.HashMap; +import java.util.Map; +import org.jetbrains.annotations.NotNull; + +/** + * Index to store table names and column names from db_schema.xml files. + */ +public class TableAndColumnNameIndex extends FileBasedIndexExtension { + public static final ID KEY = ID.create( + "com.magento.idea.magento2plugin.stubs.indexes.db_schema.tables_and_columns"); + private final KeyDescriptor myKeyDescriptor = new EnumeratorStringDescriptor(); + + @Override + public @NotNull DataIndexer getIndexer() { + return inputData -> { + final Map map = new HashMap<>(); + final PsiFile psiFile = inputData.getPsiFile(); + final XmlDocument document = ((XmlFile) psiFile).getDocument(); + final XmlTag root = ((XmlFile) psiFile).getRootTag(); + + if (!Settings.isEnabled(psiFile.getProject()) || document == null || root == null) { + return map; + } + + for (final XmlTag tableTag : root.getSubTags()) { + if (tableTag.getName().equals("table")) { + final String tableName = tableTag.getAttributeValue("name"); + map.put(tableName, null); + + for (final XmlTag columnTag : tableTag.getSubTags()) { + if (columnTag.getName().equals("column")) { + map.put(tableName + "." + columnTag.getAttributeValue("name"), null); + } + } + } + } + return map; + }; + } + + @Override + public @NotNull ID getName() { + return KEY; + } + + @Override + public @NotNull KeyDescriptor getKeyDescriptor() { + return myKeyDescriptor; + } + + @Override + public @NotNull DataExternalizer getValueExternalizer() { + return VoidDataExternalizer.INSTANCE; + } + + @Override + public int getVersion() { + return 1; + } + + @Override + public FileBasedIndex.@NotNull InputFilter getInputFilter() { + return virtualFile -> (virtualFile.getFileType() == XmlFileType.INSTANCE + && virtualFile.getNameWithoutExtension().equals("db_schema")); + } + + @Override + public boolean dependsOnFileContent() { + return true; + } +} diff --git a/testData/completion/xml/TableAndColumnNameCompletionRegistrar/constraintColumnNameMustHaveCompletion/db_schema.xml b/testData/completion/xml/TableAndColumnNameCompletionRegistrar/constraintColumnNameMustHaveCompletion/db_schema.xml new file mode 100644 index 000000000..56f8140d1 --- /dev/null +++ b/testData/completion/xml/TableAndColumnNameCompletionRegistrar/constraintColumnNameMustHaveCompletion/db_schema.xml @@ -0,0 +1,13 @@ + + + +
+ +
+ diff --git a/testData/completion/xml/TableAndColumnNameCompletionRegistrar/constraintReferenceColumnNameMustHaveCompletion/db_schema.xml b/testData/completion/xml/TableAndColumnNameCompletionRegistrar/constraintReferenceColumnNameMustHaveCompletion/db_schema.xml new file mode 100644 index 000000000..22b3e1d89 --- /dev/null +++ b/testData/completion/xml/TableAndColumnNameCompletionRegistrar/constraintReferenceColumnNameMustHaveCompletion/db_schema.xml @@ -0,0 +1,13 @@ + + + + + +
+
diff --git a/testData/completion/xml/TableAndColumnNameCompletionRegistrar/constraintTagReferenceTableMustHaveCompletion/db_schema.xml b/testData/completion/xml/TableAndColumnNameCompletionRegistrar/constraintTagReferenceTableMustHaveCompletion/db_schema.xml new file mode 100644 index 000000000..263b77e08 --- /dev/null +++ b/testData/completion/xml/TableAndColumnNameCompletionRegistrar/constraintTagReferenceTableMustHaveCompletion/db_schema.xml @@ -0,0 +1,13 @@ + + + + + +
+
diff --git a/testData/completion/xml/TableAndColumnNameCompletionRegistrar/constraintTagTableMustHaveCompletion/db_schema.xml b/testData/completion/xml/TableAndColumnNameCompletionRegistrar/constraintTagTableMustHaveCompletion/db_schema.xml new file mode 100644 index 000000000..267c35b09 --- /dev/null +++ b/testData/completion/xml/TableAndColumnNameCompletionRegistrar/constraintTagTableMustHaveCompletion/db_schema.xml @@ -0,0 +1,13 @@ + + + + + +
+
diff --git a/testData/completion/xml/TableAndColumnNameCompletionRegistrar/tableNameMustHaveCompletion/db_schema.xml b/testData/completion/xml/TableAndColumnNameCompletionRegistrar/tableNameMustHaveCompletion/db_schema.xml new file mode 100644 index 000000000..c2837d76f --- /dev/null +++ b/testData/completion/xml/TableAndColumnNameCompletionRegistrar/tableNameMustHaveCompletion/db_schema.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/testData/project/magento2/vendor/magento/module-catalog/etc/db_schema.xml b/testData/project/magento2/vendor/magento/module-catalog/etc/db_schema.xml new file mode 100644 index 000000000..0a81ef492 --- /dev/null +++ b/testData/project/magento2/vendor/magento/module-catalog/etc/db_schema.xml @@ -0,0 +1,63 @@ + + + +
+ + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+
diff --git a/testData/reference/xml/TableNameAndColumnReferenceRegistrar/constraintColumnTagMustHaveReference/db_schema.xml b/testData/reference/xml/TableNameAndColumnReferenceRegistrar/constraintColumnTagMustHaveReference/db_schema.xml new file mode 100644 index 000000000..318a0fdf4 --- /dev/null +++ b/testData/reference/xml/TableNameAndColumnReferenceRegistrar/constraintColumnTagMustHaveReference/db_schema.xml @@ -0,0 +1,13 @@ + + + + + +
+
diff --git a/testData/reference/xml/TableNameAndColumnReferenceRegistrar/constraintReferenceColumnTagMustHaveReference/db_schema.xml b/testData/reference/xml/TableNameAndColumnReferenceRegistrar/constraintReferenceColumnTagMustHaveReference/db_schema.xml new file mode 100644 index 000000000..efdccbcf2 --- /dev/null +++ b/testData/reference/xml/TableNameAndColumnReferenceRegistrar/constraintReferenceColumnTagMustHaveReference/db_schema.xml @@ -0,0 +1,13 @@ + + + + + +
+
diff --git a/testData/reference/xml/TableNameAndColumnReferenceRegistrar/constraintReferenceTableTagMustHaveReference/db_schema.xml b/testData/reference/xml/TableNameAndColumnReferenceRegistrar/constraintReferenceTableTagMustHaveReference/db_schema.xml new file mode 100644 index 000000000..89b7ff7f2 --- /dev/null +++ b/testData/reference/xml/TableNameAndColumnReferenceRegistrar/constraintReferenceTableTagMustHaveReference/db_schema.xml @@ -0,0 +1,13 @@ + + + + + +
+
diff --git a/testData/reference/xml/TableNameAndColumnReferenceRegistrar/constraintTableTagMustHaveReference/db_schema.xml b/testData/reference/xml/TableNameAndColumnReferenceRegistrar/constraintTableTagMustHaveReference/db_schema.xml new file mode 100644 index 000000000..21a41cda5 --- /dev/null +++ b/testData/reference/xml/TableNameAndColumnReferenceRegistrar/constraintTableTagMustHaveReference/db_schema.xml @@ -0,0 +1,13 @@ + + + + + +
+
diff --git a/testData/reference/xml/TableNameAndColumnReferenceRegistrar/tableTagMustHaveReference/db_schema.xml b/testData/reference/xml/TableNameAndColumnReferenceRegistrar/tableTagMustHaveReference/db_schema.xml new file mode 100644 index 000000000..5c6915496 --- /dev/null +++ b/testData/reference/xml/TableNameAndColumnReferenceRegistrar/tableTagMustHaveReference/db_schema.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/tests/com/magento/idea/magento2plugin/completion/xml/TableAndColumnNameCompletionRegistrarTest.java b/tests/com/magento/idea/magento2plugin/completion/xml/TableAndColumnNameCompletionRegistrarTest.java new file mode 100644 index 000000000..0156b97ee --- /dev/null +++ b/tests/com/magento/idea/magento2plugin/completion/xml/TableAndColumnNameCompletionRegistrarTest.java @@ -0,0 +1,60 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.completion.xml; + +import com.magento.idea.magento2plugin.magento.files.ModuleDbSchemaXml; + +/** + * Test table and column names completion in the db_schema.xml file. + */ +public class TableAndColumnNameCompletionRegistrarTest extends CompletionXmlFixtureTestCase { + private static final String CATALOG_PRODUCT_ENTITY_TABLE_NAME = "catalog_product_entity"; + + /** + * The `name` attribute of the `table` tag in `db_schema.xml` file must + * have completion based on table and column names index. + */ + public void testTableNameMustHaveCompletion() { + final String filePath = this.getFixturePath(ModuleDbSchemaXml.FILE_NAME); + assertCompletionContains(filePath, "catalog_category_entity"); + } + + /** + * The `table` attribute of the `constraint` tag in `db_schema.xml` file must + * have completion based on table and column names index. + */ + public void testConstraintTagTableMustHaveCompletion() { + final String filePath = this.getFixturePath(ModuleDbSchemaXml.FILE_NAME); + assertCompletionContains(filePath, CATALOG_PRODUCT_ENTITY_TABLE_NAME); + } + + /** + * The `referenceTable` attribute of the `constraint` tag in `db_schema.xml` file must + * have completion based on table and column names index. + */ + public void testConstraintTagReferenceTableMustHaveCompletion() { + final String filePath = this.getFixturePath(ModuleDbSchemaXml.FILE_NAME); + assertCompletionContains(filePath, CATALOG_PRODUCT_ENTITY_TABLE_NAME); + } + + /** + * The `column` attribute of the `constraint` tag in `db_schema.xml` file must + * have completion based on table and column names index. + */ + public void testConstraintColumnNameMustHaveCompletion() { + final String filePath = this.getFixturePath(ModuleDbSchemaXml.FILE_NAME); + assertCompletionContains(filePath, "children_count"); + } + + /** + * The `referenceColumn` attribute of the `constraint` tag in `db_schema.xml` file must + * have completion based on table and column names index. + */ + public void testConstraintReferenceColumnNameMustHaveCompletion() { + final String filePath = this.getFixturePath(ModuleDbSchemaXml.FILE_NAME); + assertCompletionContains(filePath, "attribute_set_id"); + } +} diff --git a/tests/com/magento/idea/magento2plugin/reference/BaseReferenceTestCase.java b/tests/com/magento/idea/magento2plugin/reference/BaseReferenceTestCase.java index c03eceac9..21c97c528 100644 --- a/tests/com/magento/idea/magento2plugin/reference/BaseReferenceTestCase.java +++ b/tests/com/magento/idea/magento2plugin/reference/BaseReferenceTestCase.java @@ -8,19 +8,17 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiReference; +import com.intellij.psi.ResolveResult; import com.intellij.psi.xml.XmlAttributeValue; -import com.intellij.psi.xml.XmlFile; import com.intellij.psi.xml.XmlTag; import com.jetbrains.php.lang.psi.elements.PhpClass; import com.magento.idea.magento2plugin.inspections.BaseInspectionsTestCase; import com.magento.idea.magento2plugin.magento.packages.File; +import com.magento.idea.magento2plugin.reference.xml.PolyVariantReferenceBase; public abstract class BaseReferenceTestCase extends BaseInspectionsTestCase { - - private static final String testDataFolderPath = "testData" //NOPMD - + File.separator - + "reference" - + File.separator; + private static final String testDataFolderPath = "testData" + File.separator//NOPMD + + "reference" + File.separator; @Override protected void setUp() throws Exception { @@ -29,11 +27,8 @@ protected void setUp() throws Exception { } protected void assertHasReferenceToXmlAttributeValue(final String reference) { - final String referenceNotFound //NOPMD - = "Failed that element contains reference to the attribute value `%s`"; - final PsiElement element = getElementFromCaret(); - for (final PsiReference psiReference : element.getReferences()) { + for (final PsiReference psiReference: element.getReferences()) { final PsiElement resolved = psiReference.resolve(); if (!(resolved instanceof XmlAttributeValue)) { continue; @@ -43,54 +38,49 @@ protected void assertHasReferenceToXmlAttributeValue(final String reference) { return; } } + final String referenceNotFound = + "Failed that element contains reference to the attribute value `%s`"; fail(String.format(referenceNotFound, reference)); } protected void assertHasReferenceToXmlTag(final String tagName) { - final String referenceNotFound //NOPMD - = "Failed that element contains reference to the XML tag `%s`"; - final PsiElement element = getElementFromCaret(); - for (final PsiReference psiReference : element.getReferences()) { - final PsiElement resolved = psiReference.resolve(); - if (!(resolved instanceof XmlTag)) { - continue; - } - - if (((XmlTag) resolved).getName().equals(tagName)) { - return; + for (final PsiReference psiReference: element.getReferences()) { + if (psiReference instanceof PolyVariantReferenceBase) { + final ResolveResult[] resolveResults + = ((PolyVariantReferenceBase) psiReference).multiResolve(true); + + for (final ResolveResult resolveResult : resolveResults) { + final PsiElement resolved = resolveResult.getElement(); + if (!(resolved instanceof XmlTag)) { + continue; + } + + if (((XmlTag) resolved).getName().equals(tagName)) { + return; + } + } + } else { + final PsiElement resolved = psiReference.resolve(); + if (!(resolved instanceof XmlTag)) { + continue; + } + + if (((XmlTag) resolved).getName().equals(tagName)) { + return; + } } } - - fail(String.format(referenceNotFound, tagName)); - } - - protected void assertHasReferenceToXmlFile(final String fileName) { - final String referenceNotFound //NOPMD + final String referenceNotFound = "Failed that element contains reference to the XML tag `%s`"; - final PsiElement element = getElementFromCaret(); - for (final PsiReference psiReference : element.getReferences()) { - final PsiElement resolved = psiReference.resolve(); - if (!(resolved instanceof XmlFile)) { - continue; - } - - if (((XmlFile) resolved).getName().equals(fileName)) { - return; - } - } - - fail(String.format(referenceNotFound, fileName)); + fail(String.format(referenceNotFound, tagName)); } protected void assertHasReferenceToFile(final String reference) { - final String referenceNotFound //NOPMD - = "Failed that element contains reference to the file `%s`"; - final PsiElement element = getElementFromCaret(); - for (final PsiReference psiReference : element.getReferences()) { + for (final PsiReference psiReference: element.getReferences()) { final PsiElement resolved = psiReference.resolve(); if (!(resolved instanceof PsiFile)) { continue; @@ -99,20 +89,18 @@ protected void assertHasReferenceToFile(final String reference) { return; } } + final String referenceNotFound = "Failed that element contains reference to the file `%s`"; fail(String.format(referenceNotFound, reference)); } - @SuppressWarnings("PMD") protected void assertHasReferencePhpClass(final String phpClassFqn) { final PsiElement element = getElementFromCaret(); final PsiReference[] references = element.getReferences(); - String result = ((PhpClass) references[references.length - 1] - .resolve()) - .getPresentableFQN(); - assertEquals( + assertEquals(//NOPMD phpClassFqn, - result + ((PhpClass) references[references.length - 1].resolve()) + .getPresentableFQN() ); } diff --git a/tests/com/magento/idea/magento2plugin/reference/xml/TableNameAndColumnReferenceRegistrarTest.java b/tests/com/magento/idea/magento2plugin/reference/xml/TableNameAndColumnReferenceRegistrarTest.java new file mode 100644 index 000000000..97adcd998 --- /dev/null +++ b/tests/com/magento/idea/magento2plugin/reference/xml/TableNameAndColumnReferenceRegistrarTest.java @@ -0,0 +1,69 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.reference.xml; + +import com.magento.idea.magento2plugin.magento.files.ModuleDbSchemaXml; + +/** + * Test table and columns name references in the db_schema.xml file. + */ +public class TableNameAndColumnReferenceRegistrarTest extends ReferenceXmlFixtureTestCase { + + /** + * The `name` attribute of the `table` tag in a `db_schema.xml` must + * have reference to the `name` attribute of the another `table` tag. + */ + public void testTableTagMustHaveReference() { + final String filePath = this.getFixturePath(ModuleDbSchemaXml.FILE_NAME); + myFixture.configureByFile(filePath); + + assertHasReferenceToXmlTag(ModuleDbSchemaXml.XML_TAG_TABLE); + } + + /** + * The `table` attribute of the `constraint` tag in a `db_schema.xml` must + * have reference to the `name` attribute of the another `table` tag. + */ + public void testConstraintTableTagMustHaveReference() { + final String filePath = this.getFixturePath(ModuleDbSchemaXml.FILE_NAME); + myFixture.configureByFile(filePath); + + assertHasReferenceToXmlTag(ModuleDbSchemaXml.XML_TAG_TABLE); + } + + /** + * The `referenceTable` attribute of the `constraint` tag in a `db_schema.xml` must + * have reference to the `name` attribute of the another `table` tag. + */ + public void testConstraintReferenceTableTagMustHaveReference() { + final String filePath = this.getFixturePath(ModuleDbSchemaXml.FILE_NAME); + myFixture.configureByFile(filePath); + + assertHasReferenceToXmlTag(ModuleDbSchemaXml.XML_TAG_TABLE); + } + + /** + * The `column` attribute of the `constraint` tag in a `db_schema.xml` must + * have reference to the `name` attribute of the `column` tag. + */ + public void testConstraintColumnTagMustHaveReference() { + final String filePath = this.getFixturePath(ModuleDbSchemaXml.FILE_NAME); + myFixture.configureByFile(filePath); + + assertHasReferenceToXmlTag(ModuleDbSchemaXml.XML_TAG_COLUMN); + } + + /** + * The `referenceColumn` attribute of the `constraint` tag in a `db_schema.xml` must + * have reference to the `name` attribute of the `column` tag. + */ + public void testConstraintReferenceColumnTagMustHaveReference() { + final String filePath = this.getFixturePath(ModuleDbSchemaXml.FILE_NAME); + myFixture.configureByFile(filePath); + + assertHasReferenceToXmlTag(ModuleDbSchemaXml.XML_TAG_COLUMN); + } +} From 707cb213490f738cba18f5438254dc8bdd00824a Mon Sep 17 00:00:00 2001 From: bohdan-harniuk Date: Sun, 25 Oct 2020 21:11:13 +0200 Subject: [PATCH 2/4] Changed index name --- resources/META-INF/plugin.xml | 2 +- .../completion/provider/ColumnNameCompletionProvider.java | 4 ++-- .../completion/provider/TableNameCompletionProvider.java | 4 ++-- src/com/magento/idea/magento2plugin/indexes/IndexManager.java | 4 ++-- .../reference/provider/TableColumnNamesReferenceProvider.java | 4 ++-- ...lumnNameIndex.java => DeclarativeSchemaElementsIndex.java} | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) rename src/com/magento/idea/magento2plugin/stubs/indexes/xml/{TableAndColumnNameIndex.java => DeclarativeSchemaElementsIndex.java} (97%) diff --git a/resources/META-INF/plugin.xml b/resources/META-INF/plugin.xml index b93bff8b0..f72fa7645 100644 --- a/resources/META-INF/plugin.xml +++ b/resources/META-INF/plugin.xml @@ -125,8 +125,8 @@ + - diff --git a/src/com/magento/idea/magento2plugin/completion/provider/ColumnNameCompletionProvider.java b/src/com/magento/idea/magento2plugin/completion/provider/ColumnNameCompletionProvider.java index 04039759a..7f0780876 100644 --- a/src/com/magento/idea/magento2plugin/completion/provider/ColumnNameCompletionProvider.java +++ b/src/com/magento/idea/magento2plugin/completion/provider/ColumnNameCompletionProvider.java @@ -16,7 +16,7 @@ import com.intellij.util.ProcessingContext; import com.intellij.util.indexing.FileBasedIndex; import com.magento.idea.magento2plugin.magento.files.ModuleDbSchemaXml; -import com.magento.idea.magento2plugin.stubs.indexes.xml.TableAndColumnNameIndex; +import com.magento.idea.magento2plugin.stubs.indexes.xml.DeclarativeSchemaElementsIndex; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; @@ -58,7 +58,7 @@ protected void addCompletions( return; } final Collection tableAndColumnNames = FileBasedIndex.getInstance().getAllKeys( - TableAndColumnNameIndex.KEY, position.getProject() + DeclarativeSchemaElementsIndex.KEY, position.getProject() ); final List filteredColumnNames = tableAndColumnNames.stream() .filter(name -> name.contains(targetTableName + ".")).collect(Collectors.toList()) diff --git a/src/com/magento/idea/magento2plugin/completion/provider/TableNameCompletionProvider.java b/src/com/magento/idea/magento2plugin/completion/provider/TableNameCompletionProvider.java index 1a4f625f4..2d4d781be 100644 --- a/src/com/magento/idea/magento2plugin/completion/provider/TableNameCompletionProvider.java +++ b/src/com/magento/idea/magento2plugin/completion/provider/TableNameCompletionProvider.java @@ -12,7 +12,7 @@ import com.intellij.psi.PsiElement; import com.intellij.util.ProcessingContext; import com.intellij.util.indexing.FileBasedIndex; -import com.magento.idea.magento2plugin.stubs.indexes.xml.TableAndColumnNameIndex; +import com.magento.idea.magento2plugin.stubs.indexes.xml.DeclarativeSchemaElementsIndex; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; @@ -34,7 +34,7 @@ protected void addCompletions( } final Collection tableNames = FileBasedIndex.getInstance().getAllKeys( - TableAndColumnNameIndex.KEY, position.getProject() + DeclarativeSchemaElementsIndex.KEY, position.getProject() ); final List filteredTableNames = tableNames.stream() .filter(name -> !name.contains(".")).collect(Collectors.toList()); diff --git a/src/com/magento/idea/magento2plugin/indexes/IndexManager.java b/src/com/magento/idea/magento2plugin/indexes/IndexManager.java index da161418d..9653d5c14 100644 --- a/src/com/magento/idea/magento2plugin/indexes/IndexManager.java +++ b/src/com/magento/idea/magento2plugin/indexes/IndexManager.java @@ -25,9 +25,9 @@ import com.magento.idea.magento2plugin.stubs.indexes.mftf.SectionIndex; import com.magento.idea.magento2plugin.stubs.indexes.mftf.TestNameIndex; import com.magento.idea.magento2plugin.stubs.indexes.xml.AclResourceIndex; +import com.magento.idea.magento2plugin.stubs.indexes.xml.DeclarativeSchemaElementsIndex; import com.magento.idea.magento2plugin.stubs.indexes.xml.MenuIndex; import com.magento.idea.magento2plugin.stubs.indexes.xml.PhpClassNameIndex; -import com.magento.idea.magento2plugin.stubs.indexes.xml.TableAndColumnNameIndex; import com.magento.idea.magento2plugin.stubs.indexes.xml.UIComponentIndex; @SuppressWarnings({"PMD.ClassNamingConventions", "PMD.UseUtilityClass"}) @@ -43,7 +43,7 @@ public static void manualReindex() { // xml|di configuration PluginIndex.KEY, VirtualTypeIndex.KEY, - TableAndColumnNameIndex.KEY, + DeclarativeSchemaElementsIndex.KEY, // layouts BlockNameIndex.KEY, ContainerNameIndex.KEY, diff --git a/src/com/magento/idea/magento2plugin/reference/provider/TableColumnNamesReferenceProvider.java b/src/com/magento/idea/magento2plugin/reference/provider/TableColumnNamesReferenceProvider.java index 81d74fcf1..b1c598112 100644 --- a/src/com/magento/idea/magento2plugin/reference/provider/TableColumnNamesReferenceProvider.java +++ b/src/com/magento/idea/magento2plugin/reference/provider/TableColumnNamesReferenceProvider.java @@ -23,7 +23,7 @@ import com.intellij.util.indexing.FileBasedIndex; import com.magento.idea.magento2plugin.magento.files.ModuleDbSchemaXml; import com.magento.idea.magento2plugin.reference.xml.PolyVariantReferenceBase; -import com.magento.idea.magento2plugin.stubs.indexes.xml.TableAndColumnNameIndex; +import com.magento.idea.magento2plugin.stubs.indexes.xml.DeclarativeSchemaElementsIndex; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -80,7 +80,7 @@ public PsiReference[] getReferencesByElement( } } final Collection files = FileBasedIndex.getInstance() - .getContainingFiles(TableAndColumnNameIndex.KEY, identifier, + .getContainingFiles(DeclarativeSchemaElementsIndex.KEY, identifier, GlobalSearchScope.getScopeRestrictedByFileTypes( GlobalSearchScope.allScope(element.getProject()), XmlFileType.INSTANCE diff --git a/src/com/magento/idea/magento2plugin/stubs/indexes/xml/TableAndColumnNameIndex.java b/src/com/magento/idea/magento2plugin/stubs/indexes/xml/DeclarativeSchemaElementsIndex.java similarity index 97% rename from src/com/magento/idea/magento2plugin/stubs/indexes/xml/TableAndColumnNameIndex.java rename to src/com/magento/idea/magento2plugin/stubs/indexes/xml/DeclarativeSchemaElementsIndex.java index 51396e0b1..9fb213443 100644 --- a/src/com/magento/idea/magento2plugin/stubs/indexes/xml/TableAndColumnNameIndex.java +++ b/src/com/magento/idea/magento2plugin/stubs/indexes/xml/DeclarativeSchemaElementsIndex.java @@ -27,7 +27,7 @@ /** * Index to store table names and column names from db_schema.xml files. */ -public class TableAndColumnNameIndex extends FileBasedIndexExtension { +public class DeclarativeSchemaElementsIndex extends FileBasedIndexExtension { public static final ID KEY = ID.create( "com.magento.idea.magento2plugin.stubs.indexes.db_schema.tables_and_columns"); private final KeyDescriptor myKeyDescriptor = new EnumeratorStringDescriptor(); From 0ac99de8b0d3371e28767bd57f19cf689ce09361 Mon Sep 17 00:00:00 2001 From: bohdan-harniuk Date: Tue, 27 Oct 2020 18:30:37 +0200 Subject: [PATCH 3/4] Fixed self references --- .../TableColumnNamesReferenceProvider.java | 3 ++ .../reference/BaseReferenceTestCase.java | 30 ++++++++++++++++--- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/com/magento/idea/magento2plugin/reference/provider/TableColumnNamesReferenceProvider.java b/src/com/magento/idea/magento2plugin/reference/provider/TableColumnNamesReferenceProvider.java index b1c598112..47e1c1218 100644 --- a/src/com/magento/idea/magento2plugin/reference/provider/TableColumnNamesReferenceProvider.java +++ b/src/com/magento/idea/magento2plugin/reference/provider/TableColumnNamesReferenceProvider.java @@ -91,6 +91,9 @@ public PsiReference[] getReferencesByElement( final PsiManager psiManager = PsiManager.getInstance(element.getProject()); for (final VirtualFile virtualFile : files) { + if (virtualFile.equals(element.getContainingFile().getVirtualFile())) { + continue; + } final XmlDocument xmlDocument = ((XmlFile) Objects.requireNonNull( psiManager.findFile(virtualFile)) ).getDocument(); diff --git a/tests/com/magento/idea/magento2plugin/reference/BaseReferenceTestCase.java b/tests/com/magento/idea/magento2plugin/reference/BaseReferenceTestCase.java index 21c97c528..94f8b20b4 100644 --- a/tests/com/magento/idea/magento2plugin/reference/BaseReferenceTestCase.java +++ b/tests/com/magento/idea/magento2plugin/reference/BaseReferenceTestCase.java @@ -10,6 +10,7 @@ import com.intellij.psi.PsiReference; import com.intellij.psi.ResolveResult; import com.intellij.psi.xml.XmlAttributeValue; +import com.intellij.psi.xml.XmlFile; import com.intellij.psi.xml.XmlTag; import com.jetbrains.php.lang.psi.elements.PhpClass; import com.magento.idea.magento2plugin.inspections.BaseInspectionsTestCase; @@ -80,7 +81,7 @@ protected void assertHasReferenceToXmlTag(final String tagName) { protected void assertHasReferenceToFile(final String reference) { final PsiElement element = getElementFromCaret(); - for (final PsiReference psiReference: element.getReferences()) { + for (final PsiReference psiReference : element.getReferences()) { final PsiElement resolved = psiReference.resolve(); if (!(resolved instanceof PsiFile)) { continue; @@ -94,13 +95,34 @@ protected void assertHasReferenceToFile(final String reference) { fail(String.format(referenceNotFound, reference)); } + protected void assertHasReferenceToXmlFile(final String fileName) { + final PsiElement element = getElementFromCaret(); + for (final PsiReference psiReference : element.getReferences()) { + final PsiElement resolved = psiReference.resolve(); + if (!(resolved instanceof XmlFile)) { + continue; + } + + if (((XmlFile) resolved).getName().equals(fileName)) { + return; + } + } + final String referenceNotFound + = "Failed that element contains reference to the XML tag `%s`"; + + fail(String.format(referenceNotFound, fileName)); + } + + @SuppressWarnings("PMD") protected void assertHasReferencePhpClass(final String phpClassFqn) { final PsiElement element = getElementFromCaret(); final PsiReference[] references = element.getReferences(); - assertEquals(//NOPMD + String result = ((PhpClass) references[references.length - 1] + .resolve()) + .getPresentableFQN(); + assertEquals( phpClassFqn, - ((PhpClass) references[references.length - 1].resolve()) - .getPresentableFQN() + result ); } From de0d76a95a3f2c05422913798e63f40b421002bc Mon Sep 17 00:00:00 2001 From: Vitaliy Boyko Date: Wed, 28 Oct 2020 19:29:03 +0200 Subject: [PATCH 4/4] Fixed version --- resources/META-INF/plugin.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/META-INF/plugin.xml b/resources/META-INF/plugin.xml index f72fa7645..854c516e4 100644 --- a/resources/META-INF/plugin.xml +++ b/resources/META-INF/plugin.xml @@ -7,7 +7,7 @@ com.magento.idea.magento2plugin Magento PhpStorm - 2.0.1 + 2.1.0 Magento Inc.