Skip to content

Commit 09b3683

Browse files
author
Vitaliy
authored
Merge pull request #351 from bohdan-harniuk/add-index-reference-and-comletion-to-db-schema-tables-and-columns
Added index, completion and references for table names, column names …
2 parents ea2f087 + de0d76a commit 09b3683

File tree

23 files changed

+988
-36
lines changed

23 files changed

+988
-36
lines changed

resources/META-INF/plugin.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<idea-plugin>
88
<id>com.magento.idea.magento2plugin</id>
99
<name>Magento PhpStorm</name>
10-
<version>2.0.1</version>
10+
<version>2.1.0</version>
1111
<vendor url="https://github.com/magento/magento2-phpstorm-plugin">Magento Inc.</vendor>
1212

1313
<description><![CDATA[
@@ -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.DeclarativeSchemaElementsIndex" />
128129
<fileBasedIndex implementation="com.magento.idea.magento2plugin.stubs.indexes.xml.UIComponentIndex" />
129130

130131
<codeInsight.lineMarkerProvider language="PHP" implementationClass="com.magento.idea.magento2plugin.linemarker.php.PluginLineMarkerProvider"/>
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.DeclarativeSchemaElementsIndex;
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+
DeclarativeSchemaElementsIndex.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.DeclarativeSchemaElementsIndex;
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+
DeclarativeSchemaElementsIndex.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
@@ -324,6 +324,64 @@ public XmlCompletionContributor() {
324324
new MenuCompletionProvider()
325325
);
326326

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

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import com.magento.idea.magento2plugin.stubs.indexes.mftf.SectionIndex;
2626
import com.magento.idea.magento2plugin.stubs.indexes.mftf.TestNameIndex;
2727
import com.magento.idea.magento2plugin.stubs.indexes.xml.AclResourceIndex;
28+
import com.magento.idea.magento2plugin.stubs.indexes.xml.DeclarativeSchemaElementsIndex;
2829
import com.magento.idea.magento2plugin.stubs.indexes.xml.MenuIndex;
2930
import com.magento.idea.magento2plugin.stubs.indexes.xml.PhpClassNameIndex;
3031
import com.magento.idea.magento2plugin.stubs.indexes.xml.UIComponentIndex;
@@ -42,6 +43,7 @@ public static void manualReindex() {
4243
// xml|di configuration
4344
PluginIndex.KEY,
4445
VirtualTypeIndex.KEY,
46+
DeclarativeSchemaElementsIndex.KEY,
4547
// layouts
4648
BlockNameIndex.KEY,
4749
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)