Skip to content

Commit b07d4c9

Browse files
Added index, completion and references for table names, column names in db_schema.xml file
1 parent 2e1a9f5 commit b07d4c9

File tree

23 files changed

+992
-35
lines changed

23 files changed

+992
-35
lines changed

resources/META-INF/plugin.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@
125125
<fileBasedIndex implementation="com.magento.idea.magento2plugin.stubs.indexes.js.MagentoLibJsIndex" />
126126
<fileBasedIndex implementation="com.magento.idea.magento2plugin.stubs.indexes.xml.AclResourceIndex" />
127127
<fileBasedIndex implementation="com.magento.idea.magento2plugin.stubs.indexes.xml.MenuIndex" />
128+
<fileBasedIndex implementation="com.magento.idea.magento2plugin.stubs.indexes.xml.TableAndColumnNameIndex" />
128129

129130
<codeInsight.lineMarkerProvider language="PHP" implementationClass="com.magento.idea.magento2plugin.linemarker.php.PluginLineMarkerProvider"/>
130131
<codeInsight.lineMarkerProvider language="PHP" implementationClass="com.magento.idea.magento2plugin.linemarker.php.PluginTargetLineMarkerProvider"/>
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
6+
package com.magento.idea.magento2plugin.completion.provider;
7+
8+
import com.intellij.codeInsight.completion.CompletionParameters;
9+
import com.intellij.codeInsight.completion.CompletionProvider;
10+
import com.intellij.codeInsight.completion.CompletionResultSet;
11+
import com.intellij.codeInsight.lookup.LookupElementBuilder;
12+
import com.intellij.psi.PsiElement;
13+
import com.intellij.psi.impl.source.xml.XmlAttributeImpl;
14+
import com.intellij.psi.impl.source.xml.XmlTagImpl;
15+
import com.intellij.psi.xml.XmlTag;
16+
import com.intellij.util.ProcessingContext;
17+
import com.intellij.util.indexing.FileBasedIndex;
18+
import com.magento.idea.magento2plugin.magento.files.ModuleDbSchemaXml;
19+
import com.magento.idea.magento2plugin.stubs.indexes.xml.TableAndColumnNameIndex;
20+
import java.util.Collection;
21+
import java.util.List;
22+
import java.util.stream.Collectors;
23+
import org.jetbrains.annotations.NotNull;
24+
25+
/**
26+
* Provides column names for completion.
27+
*/
28+
public class ColumnNameCompletionProvider extends CompletionProvider<CompletionParameters> {
29+
@Override
30+
protected void addCompletions(
31+
final @NotNull CompletionParameters parameters,
32+
final @NotNull ProcessingContext context,
33+
final @NotNull CompletionResultSet result
34+
) {
35+
final PsiElement position = parameters.getPosition().getOriginalElement();
36+
final String currentAttrName = getCurrentAttributeName(position);
37+
if (position == null || currentAttrName == null) {
38+
return;
39+
}
40+
String targetTableAttrName;
41+
42+
switch (currentAttrName) {
43+
case ModuleDbSchemaXml.XML_ATTR_CONSTRAINT_COLUMN_NAME:
44+
targetTableAttrName = ModuleDbSchemaXml.XML_ATTR_CONSTRAINT_TABLE_NAME;
45+
break;
46+
case ModuleDbSchemaXml.XML_ATTR_CONSTRAINT_REFERENCE_COLUMN_NAME:
47+
targetTableAttrName = ModuleDbSchemaXml.XML_ATTR_CONSTRAINT_REFERENCE_TABLE_NAME;
48+
break;
49+
default:
50+
return;
51+
}
52+
final String targetTableName = getTargetTableFromPositionAndAttrName(
53+
position,
54+
targetTableAttrName
55+
);
56+
57+
if (targetTableName == null) {
58+
return;
59+
}
60+
final Collection<String> tableAndColumnNames = FileBasedIndex.getInstance().getAllKeys(
61+
TableAndColumnNameIndex.KEY, position.getProject()
62+
);
63+
final List<String> filteredColumnNames = tableAndColumnNames.stream()
64+
.filter(name -> name.contains(targetTableName + ".")).collect(Collectors.toList())
65+
.stream().map(name -> name.substring(name.indexOf(".") + 1))
66+
.collect(Collectors.toList());
67+
68+
for (final String columnName: filteredColumnNames) {
69+
result.addElement(LookupElementBuilder.create(columnName));
70+
}
71+
}
72+
73+
/**
74+
* Get attribute name from position.
75+
*
76+
* @param position PsiElement
77+
*
78+
* @return String
79+
*/
80+
private String getCurrentAttributeName(final PsiElement position) {
81+
if (position instanceof XmlAttributeImpl) {
82+
return ((XmlAttributeImpl) position).getName();
83+
} else {
84+
return getCurrentAttributeName(position.getParent());
85+
}
86+
}
87+
88+
/**
89+
* Get reference table name from current position.
90+
*
91+
* @param position PsiElement
92+
* @param targetTableAttrName String
93+
*
94+
* @return String
95+
*/
96+
private String getTargetTableFromPositionAndAttrName(
97+
final PsiElement position,
98+
final String targetTableAttrName
99+
) {
100+
if (targetTableAttrName == null) {
101+
return null;
102+
}
103+
104+
if (position instanceof XmlTagImpl
105+
&& ((XmlTag) position).getName().equals(ModuleDbSchemaXml.XML_TAG_CONSTRAINT)) {
106+
return ((XmlTag) position)
107+
.getAttributeValue(targetTableAttrName);
108+
} else {
109+
return getTargetTableFromPositionAndAttrName(
110+
position.getParent(),
111+
targetTableAttrName
112+
);
113+
}
114+
}
115+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
6+
package com.magento.idea.magento2plugin.completion.provider;
7+
8+
import com.intellij.codeInsight.completion.CompletionParameters;
9+
import com.intellij.codeInsight.completion.CompletionProvider;
10+
import com.intellij.codeInsight.completion.CompletionResultSet;
11+
import com.intellij.codeInsight.lookup.LookupElementBuilder;
12+
import com.intellij.psi.PsiElement;
13+
import com.intellij.util.ProcessingContext;
14+
import com.intellij.util.indexing.FileBasedIndex;
15+
import com.magento.idea.magento2plugin.stubs.indexes.xml.TableAndColumnNameIndex;
16+
import java.util.Collection;
17+
import java.util.List;
18+
import java.util.stream.Collectors;
19+
import org.jetbrains.annotations.NotNull;
20+
21+
/**
22+
* Provides table names for completion.
23+
*/
24+
public class TableNameCompletionProvider extends CompletionProvider<CompletionParameters> {
25+
@Override
26+
protected void addCompletions(
27+
final @NotNull CompletionParameters parameters,
28+
final @NotNull ProcessingContext context,
29+
final @NotNull CompletionResultSet result
30+
) {
31+
final PsiElement position = parameters.getPosition().getOriginalElement();
32+
if (position == null) {
33+
return;
34+
}
35+
36+
final Collection<String> tableNames = FileBasedIndex.getInstance().getAllKeys(
37+
TableAndColumnNameIndex.KEY, position.getProject()
38+
);
39+
final List<String> filteredTableNames = tableNames.stream()
40+
.filter(name -> !name.contains(".")).collect(Collectors.toList());
41+
42+
for (final String tableName: filteredTableNames) {
43+
result.addElement(LookupElementBuilder.create(tableName));
44+
}
45+
}
46+
}

src/com/magento/idea/magento2plugin/completion/xml/XmlCompletionContributor.java

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,64 @@ public XmlCompletionContributor() {
317317
new MenuCompletionProvider()
318318
);
319319

320+
// <table name="completion" /> in db_schema.xml
321+
extend(CompletionType.BASIC, psiElement(XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN)
322+
.inside(XmlPatterns.xmlAttribute().withName(ModuleDbSchemaXml.XML_ATTR_TABLE_NAME)
323+
.withParent(XmlPatterns.xmlTag().withName(ModuleDbSchemaXml.XML_TAG_TABLE)
324+
.withParent(XmlPatterns.xmlTag()
325+
.withName(ModuleDbSchemaXml.XML_TAG_SCHEMA))))
326+
.inFile(xmlFile().withName(string().matches(ModuleDbSchemaXml.FILE_NAME))),
327+
new TableNameCompletionProvider()
328+
);
329+
330+
// <constraint table="completion" /> in db_schema.xml
331+
extend(CompletionType.BASIC, psiElement(XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN)
332+
.inside(XmlPatterns.xmlAttribute()
333+
.withName(ModuleDbSchemaXml.XML_ATTR_CONSTRAINT_TABLE_NAME)
334+
.withParent(XmlPatterns.xmlTag()
335+
.withName(ModuleDbSchemaXml.XML_TAG_CONSTRAINT)
336+
.withParent(XmlPatterns.xmlTag()
337+
.withName(ModuleDbSchemaXml.XML_TAG_TABLE))))
338+
.inFile(xmlFile().withName(string().matches(ModuleDbSchemaXml.FILE_NAME))),
339+
new TableNameCompletionProvider()
340+
);
341+
342+
// <constraint referenceTable="completion" /> in db_schema.xml
343+
extend(CompletionType.BASIC, psiElement(XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN)
344+
.inside(XmlPatterns.xmlAttribute()
345+
.withName(ModuleDbSchemaXml.XML_ATTR_CONSTRAINT_REFERENCE_TABLE_NAME)
346+
.withParent(XmlPatterns.xmlTag()
347+
.withName(ModuleDbSchemaXml.XML_TAG_CONSTRAINT)
348+
.withParent(XmlPatterns.xmlTag()
349+
.withName(ModuleDbSchemaXml.XML_TAG_TABLE))))
350+
.inFile(xmlFile().withName(string().matches(ModuleDbSchemaXml.FILE_NAME))),
351+
new TableNameCompletionProvider()
352+
);
353+
354+
// <constraint column="completion" /> in db_schema.xml
355+
extend(CompletionType.BASIC, psiElement(XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN)
356+
.inside(XmlPatterns.xmlAttribute()
357+
.withName(ModuleDbSchemaXml.XML_ATTR_CONSTRAINT_COLUMN_NAME)
358+
.withParent(XmlPatterns.xmlTag()
359+
.withName(ModuleDbSchemaXml.XML_TAG_CONSTRAINT)
360+
.withParent(XmlPatterns.xmlTag()
361+
.withName(ModuleDbSchemaXml.XML_TAG_TABLE))))
362+
.inFile(xmlFile().withName(string().matches(ModuleDbSchemaXml.FILE_NAME))),
363+
new ColumnNameCompletionProvider()
364+
);
365+
366+
// <constraint referenceColumn="completion" /> in db_schema.xml
367+
extend(CompletionType.BASIC, psiElement(XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN)
368+
.inside(XmlPatterns.xmlAttribute()
369+
.withName(ModuleDbSchemaXml.XML_ATTR_CONSTRAINT_REFERENCE_COLUMN_NAME)
370+
.withParent(XmlPatterns.xmlTag()
371+
.withName(ModuleDbSchemaXml.XML_TAG_CONSTRAINT)
372+
.withParent(XmlPatterns.xmlTag()
373+
.withName(ModuleDbSchemaXml.XML_TAG_TABLE))))
374+
.inFile(xmlFile().withName(string().matches(ModuleDbSchemaXml.FILE_NAME))),
375+
new ColumnNameCompletionProvider()
376+
);
377+
320378
registerCompletionsForDifferentNesting();
321379
}
322380

src/com/magento/idea/magento2plugin/indexes/IndexManager.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import com.magento.idea.magento2plugin.stubs.indexes.xml.AclResourceIndex;
2828
import com.magento.idea.magento2plugin.stubs.indexes.xml.MenuIndex;
2929
import com.magento.idea.magento2plugin.stubs.indexes.xml.PhpClassNameIndex;
30+
import com.magento.idea.magento2plugin.stubs.indexes.xml.TableAndColumnNameIndex;
3031

3132
@SuppressWarnings({"PMD.ClassNamingConventions", "PMD.UseUtilityClass"})
3233
public class IndexManager {
@@ -41,6 +42,7 @@ public static void manualReindex() {
4142
// xml|di configuration
4243
PluginIndex.KEY,
4344
VirtualTypeIndex.KEY,
45+
TableAndColumnNameIndex.KEY,
4446
// layouts
4547
BlockNameIndex.KEY,
4648
ContainerNameIndex.KEY,
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
6+
package com.magento.idea.magento2plugin.magento.files;
7+
8+
import com.intellij.lang.Language;
9+
import com.intellij.lang.xml.XMLLanguage;
10+
11+
public class ModuleDbSchemaXml implements ModuleFileInterface {
12+
private static final ModuleDbSchemaXml INSTANCE = new ModuleDbSchemaXml();
13+
public static final String FILE_NAME = "db_schema.xml";
14+
public static final String TEMPLATE = "Magento Module Declarative Schema XML";
15+
16+
//attributes
17+
public static final String XML_ATTR_TABLE_NAME = "name";
18+
public static final String XML_ATTR_COLUMN_NAME = "name";
19+
public static final String XML_ATTR_CONSTRAINT_TABLE_NAME = "table";
20+
public static final String XML_ATTR_CONSTRAINT_REFERENCE_TABLE_NAME = "referenceTable";
21+
public static final String XML_ATTR_CONSTRAINT_COLUMN_NAME = "column";
22+
public static final String XML_ATTR_CONSTRAINT_REFERENCE_COLUMN_NAME = "referenceColumn";
23+
//tags
24+
public static final String XML_TAG_SCHEMA = "schema";
25+
public static final String XML_TAG_TABLE = "table";
26+
public static final String XML_TAG_COLUMN = "column";
27+
public static final String XML_TAG_CONSTRAINT = "constraint";
28+
29+
public static ModuleDbSchemaXml getInstance() {
30+
return INSTANCE;
31+
}
32+
33+
@Override
34+
public String getFileName() {
35+
return FILE_NAME;
36+
}
37+
38+
@Override
39+
public String getTemplate() {
40+
return TEMPLATE;
41+
}
42+
43+
@Override
44+
public Language getLanguage() {
45+
return XMLLanguage.INSTANCE;
46+
}
47+
}

0 commit comments

Comments
 (0)