Skip to content

Added completion and reference for module names in config.php with tests #374

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Nov 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
<projectService serviceImplementation="com.magento.idea.magento2plugin.project.Settings"/>

<completion.contributor language="XML" implementationClass="com.magento.idea.magento2plugin.completion.xml.XmlCompletionContributor" id="xml" />
<completion.contributor language="PHP" implementationClass="com.magento.idea.magento2plugin.completion.php.PhpCompletionContributor" id="php" />

<psi.referenceContributor language="XML" implementation="com.magento.idea.magento2plugin.reference.xml.XmlReferenceContributor"/>
<psi.referenceContributor language="PHP" implementation="com.magento.idea.magento2plugin.reference.php.PhpReferenceContributor"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

package com.magento.idea.magento2plugin.completion.php;

import com.intellij.codeInsight.completion.CompletionContributor;
import com.intellij.codeInsight.completion.CompletionType;
import com.magento.idea.magento2plugin.completion.provider.ModuleNameCompletionProvider;
import com.magento.idea.magento2plugin.util.php.PhpPatternsHelper;

@SuppressWarnings({
"PMD.CallSuperInConstructor",
})
public class PhpCompletionContributor extends CompletionContributor {

/**
* Constructor.
*/
public PhpCompletionContributor() {
/*
'modules' => [
'Vendor_Module' => 1
]
*/
extend(
CompletionType.BASIC,
PhpPatternsHelper.CONFIGPHP_COMPLETION,
new ModuleNameCompletionProvider()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,33 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

package com.magento.idea.magento2plugin.reference.php;

import com.intellij.psi.PsiReferenceContributor;
import com.intellij.psi.PsiReferenceRegistrar;
import com.magento.idea.magento2plugin.util.php.PhpPatternsHelper;
import com.magento.idea.magento2plugin.reference.provider.EventDispatchReferenceProvider;
import com.magento.idea.magento2plugin.reference.provider.ModuleNameReferenceProvider;
import com.magento.idea.magento2plugin.util.php.PhpPatternsHelper;
import org.jetbrains.annotations.NotNull;

public class PhpReferenceContributor extends PsiReferenceContributor {
@Override
public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
public void registerReferenceProviders(@NotNull final PsiReferenceRegistrar registrar) {
// ->dispatch("event_name")
registrar.registerReferenceProvider(
PhpPatternsHelper.STRING_METHOD_ARGUMENT,
new EventDispatchReferenceProvider()
);

/*
'modules' => [
'Vendor_Module' => 1
]
*/
registrar.registerReferenceProvider(
PhpPatternsHelper.CONFIGPHP_MODULENAME,
new ModuleNameReferenceProvider()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,51 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

package com.magento.idea.magento2plugin.util.php;

import com.intellij.patterns.ElementPattern;
import com.intellij.patterns.PlatformPatterns;
import com.intellij.patterns.StandardPatterns;
import com.intellij.psi.PsiElement;
import com.jetbrains.php.lang.PhpLanguage;
import com.jetbrains.php.lang.lexer.PhpTokenTypes;
import com.jetbrains.php.lang.patterns.PhpPatterns;
import com.jetbrains.php.lang.psi.elements.ArrayHashElement;
import com.jetbrains.php.lang.psi.elements.ParameterList;
import com.jetbrains.php.lang.psi.elements.PhpPsiElement;
import com.jetbrains.php.lang.psi.elements.StringLiteralExpression;

public class PhpPatternsHelper {
public static final ElementPattern<? extends PsiElement> STRING_METHOD_ARGUMENT =
PhpPatterns
.phpLiteralExpression()
.withParent(
PlatformPatterns
.psiElement(ParameterList.class)
.withParent(
PhpPatterns
.phpFunctionReference()
PhpPatterns
.phpLiteralExpression()
.withParent(
PlatformPatterns
.psiElement(ParameterList.class)
.withParent(
PhpPatterns
.phpFunctionReference()
)
).withLanguage(PhpLanguage.INSTANCE);

public static final ElementPattern<? extends PsiElement> CONFIGPHP_MODULENAME =
PlatformPatterns.psiElement(StringLiteralExpression.class)
.withSuperParent(5,PlatformPatterns.psiElement(ArrayHashElement.class)
.withChild(PlatformPatterns.psiElement(PhpPsiElement.class)
.withChild(PlatformPatterns.psiElement(StringLiteralExpression.class)
.withText(StandardPatterns.string().contains("modules").withLength(9))
)
)
);

public static final ElementPattern<? extends PsiElement> CONFIGPHP_COMPLETION =
PlatformPatterns.psiElement(PhpTokenTypes.STRING_LITERAL_SINGLE_QUOTE)
.withSuperParent(6, PlatformPatterns.psiElement(ArrayHashElement.class)
.withChild(PlatformPatterns.psiElement(PhpPsiElement.class)
.withChild(PlatformPatterns.psiElement(StringLiteralExpression.class)
.withText(StandardPatterns.string().contains("modules").withLength(9))
)
)
).withLanguage(PhpLanguage.INSTANCE);
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

return [
'modules' => [
'Magento_C<caret>' => 1
]
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

return [
'moduless' => [
'Magento_C<caret>' => 1
]
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

return [
'modules' => [
'Magento_Catalog<caret>' => 1
]
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

return [
'moduless' => [
'Magento_Catalog<caret>' => 1
]
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/*
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

package com.magento.idea.magento2plugin.completion;

import com.magento.idea.magento2plugin.BaseProjectTestCase;
import com.magento.idea.magento2plugin.magento.packages.File;
import java.util.Arrays;
import java.util.List;

public abstract class BaseCompletionTestCase extends BaseProjectTestCase {
private static final String MESSAGE_NO_LOOKUP = "No lookup element was provided";
private final String testDataFolderPath
= "testData" + File.separator + "completion" + File.separator;

@Override
protected void setUp() throws Exception {
super.setUp();
myFixture.setTestDataPath(testDataFolderPath);
}

private void configureFixture(final String filePath) {
myFixture.configureByFile(filePath);
myFixture.completeBasic();
}

/**
* Assert that completion suggestions contains the given lookup strings.
*/
public void assertCompletionContains(final String filePath, final String... lookupStrings) {
configureFixture(filePath);

final String messageEmptyLookup = "Failed that completion contains `%s`";
final String messageComplationContains = "Failed that completion contains `%s` in `%s`";

checkContainsCompletion(lookupStrings, messageEmptyLookup, messageComplationContains);
}

protected void assertFileContainsCompletions(
final String filePath,
final String... lookupStrings
) {
configureFixture(filePath);

final String messageEmptyLookup
= "Failed that completion contains `%s` for file " + filePath;
final String messageCompletionContains
= "Failed that completion contains `%s` in `%s` for file " + filePath;

checkContainsCompletion(lookupStrings, messageEmptyLookup, messageCompletionContains);
}

protected void assertFileNotContainsCompletions(
final String filePath,
final String... lookupStrings
) {
configureFixture(filePath);

final String messageCompletionNotContains
= "Failed that completion does not contain `%s` in `%s` for file " + filePath;

checkDoesNotContainCompletion(
lookupStrings, messageCompletionNotContains
);
}

protected void assertCompletionNotShowing(final String filePath) {
configureFixture(filePath);

final List<String> lookupElements = myFixture.getLookupElementStrings();

if (lookupElements != null && !lookupElements.isEmpty()) {
final String messageCompletionDoesNotShow
= "Failed asserting that completion does not show up";

fail(messageCompletionDoesNotShow);
}
}

protected void checkContainsCompletion(
final String[] lookupStrings,
final String emptyLookupError,
final String completionContainsError
) {
if (lookupStrings.length == 0) {
fail(MESSAGE_NO_LOOKUP);
}

final List<String> lookupElements = myFixture.getLookupElementStrings();

if (lookupElements == null || lookupElements.isEmpty()) {
fail(String.format(emptyLookupError, Arrays.toString(lookupStrings)));
}

for (final String lookupString : lookupStrings) {
if (!lookupElements.contains(lookupString)) {
fail(String.format(
completionContainsError, lookupString, lookupElements.toString())
);
}
}
}

protected void checkDoesNotContainCompletion(
final String[] lookupStrings,
final String completionDoesNotContainError
) {
if (lookupStrings.length == 0) {
fail(MESSAGE_NO_LOOKUP);
}

final List<String> lookupElements = myFixture.getLookupElementStrings();

if (lookupElements != null) {
for (final String lookupString : lookupStrings) {
if (lookupElements.contains(lookupString)) {
fail(String.format(
completionDoesNotContainError, lookupString, lookupElements.toString())
);
}
}
}
}

protected abstract String getFixturePath(String fileName);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

package com.magento.idea.magento2plugin.completion.php;

import com.magento.idea.magento2plugin.completion.BaseCompletionTestCase;
import com.magento.idea.magento2plugin.magento.packages.File;

public abstract class CompletionPhpFixtureTestCase extends BaseCompletionTestCase {
private static final String FIXTURES_FOLDER_PATH = "php" + File.separator;

@Override
protected String getFixturePath(final String fileName) {
return prepareFixturePath(fileName, FIXTURES_FOLDER_PATH);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

package com.magento.idea.magento2plugin.completion.php;

public class ConfigPhpModuleCompletionRegistrarTest extends CompletionPhpFixtureTestCase {
private static final String[] LOOKUP_MODULE_NAMES = {
"Magento_Catalog",
"Magento_Config"
};

/**
* Tests for module name completion under array key 'modules' in config.php
*/
public void testModuleNameMustHaveCompletion() {
final String filePath = this.getFixturePath("config.php");
myFixture.copyFileToProject(filePath);

assertFileContainsCompletions(filePath, LOOKUP_MODULE_NAMES);
}

/**
* Tests for no module name completion under a different array key in config.php
*/
public void testModuleNameMustNotHaveCompletion() {
final String filePath = this.getFixturePath("config.php");
myFixture.copyFileToProject(filePath);

assertCompletionNotShowing(filePath);
}
}
Loading