Skip to content

Commit

Permalink
class finder flow unification
Browse files Browse the repository at this point in the history
  • Loading branch information
maxfilatov committed Jan 2, 2016
1 parent 811c75f commit 5992c73
Show file tree
Hide file tree
Showing 12 changed files with 65 additions and 127 deletions.
2 changes: 1 addition & 1 deletion META-INF/plugin.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<idea-plugin version="2" url="https://github.com/maxfilatov/phpuaca/">
<id>com.phpuaca</id>
<name>PHPUnit Autocomplete Assistant</name>
<version>1.2.1</version>
<version>1.3.0-unstable</version>
<vendor url="https://github.com/maxfilatov/phpuaca/">Max Filatov</vendor>

<description><![CDATA[
Expand Down
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ PHPUnit Autocomplete Assistant
==============================
PhpStorm plugin to provide smart autocomplete for mocked class methods.

Supported versions of PhpStorm: 7.1, 8.
Supported all versions of PhpStorm since 7.1

Features are available for method definition arguments of these PHPUnit methods:
* `PHPUnit_Framework_MockObject_MockBuilder::setMethods`
Expand All @@ -26,5 +26,10 @@ Releases

Installation
------------
Stable version:
* Go to `PhpStorm -> Preferences... -> Plugins -> Browse repositories ...` and search for PHPUnit Autocomplete Assistant plugin
* Restart PhpStorm

Latest version:
* Go to `PhpStorm -> Preferences... -> Plugins -> Install plugin from disk...` and choose jar file
* Restart PhpStorm
3 changes: 1 addition & 2 deletions src/com/phpuaca/completion/StringLiteralContributor.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ protected void addCompletions(@NotNull CompletionParameters completionParameters
if (originalPosition != null) {
Filter filter = FilterFactory.getInstance().getFilter(originalPosition.getParent());
if (filter != null) {
Project project = originalPosition.getProject();
List<LookupElement> elements = (new LookupElementProvider()).find(project, filter);
List<LookupElement> elements = (new LookupElementProvider()).find(filter);
completionResultSet.addAllElements(elements);
}
}
Expand Down
21 changes: 5 additions & 16 deletions src/com/phpuaca/completion/filter/Filter.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocMethod;
import com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocProperty;
import com.jetbrains.php.lang.psi.elements.*;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.List;
Expand All @@ -18,8 +17,7 @@ abstract public class Filter {
private List<String> allowedModifiers;
private List<String> disallowedMethods;

private ClassConstantReference classConstantReference;
private String className;
private PhpClass phpClass;

public Filter(FilterContext context)
{
Expand Down Expand Up @@ -113,22 +111,13 @@ protected boolean isModifierAllowed(PhpModifier modifier)
return isModifierAllowed(modifier.toString());
}

public void setClassConstantReference(@Nullable ClassConstantReference value)
public void setPhpClass(PhpClass phpClass)
{
classConstantReference = value;
this.phpClass = phpClass;
}

@Nullable
public ClassConstantReference getClassConstantReference()
public PhpClass getPhpClass()
{
return classConstantReference;
}

protected void setClassName(String className) {
this.className = className;
}

public String getClassName() {
return className;
return phpClass;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,7 @@ public InvocationMockerFilter(FilterContext context) {
allowModifier(PhpModifier.PROTECTED_ABSTRACT_DYNAMIC);
allowModifier(PhpModifier.PROTECTED_IMPLEMENTED_DYNAMIC);

if (classFinderResult.getClassConstantReference() != null) {
setClassConstantReference(classFinderResult.getClassConstantReference());
}
if (classFinderResult.getClassName() != null) {
setClassName(classFinderResult.getClassName());
}
setPhpClass(classFinderResult.getPhpClass());

MethodReference definitionMethodReference = (new PhpMethodChain(methodReference)).findMethodReference("setMethods");
if (definitionMethodReference == null) {
Expand Down
13 changes: 11 additions & 2 deletions src/com/phpuaca/completion/filter/MethodMockFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,34 @@
import com.intellij.psi.util.PsiTreeUtil;
import com.jetbrains.php.lang.psi.elements.*;
import com.phpuaca.completion.filter.util.ClassFinder;
import com.phpuaca.completion.util.PhpClassResolver;

public class MethodMockFilter extends Filter {

public MethodMockFilter(FilterContext context) {
super(context);

PhpClass phpClass = null;
ParameterList parameterList = context.getMethodReference().getParameterList();
ClassConstantReference classConstantReference = PsiTreeUtil.getChildOfType(parameterList, ClassConstantReference.class);
if (classConstantReference == null) {
// MethodMock::callProtectedMethod($Variable, 'doSomething');
Variable variable = PsiTreeUtil.getChildOfType(parameterList, Variable.class);
if (variable != null) {
ClassFinder.Result classFinderResult = (new ClassFinder()).find(variable);
if (classFinderResult != null) {
classConstantReference = classFinderResult.getClassConstantReference();
phpClass = classFinderResult.getPhpClass();
}
}
} else {
phpClass = (new PhpClassResolver()).resolveByClassConstantReference(classConstantReference);
}

if (phpClass == null) {
return;
}

setClassConstantReference(classConstantReference);
setPhpClass(phpClass);

String methodName = context.getFilterConfigItem().getMethodName();
if (methodName.equals("callProtectedMethod")) {
Expand Down
7 changes: 1 addition & 6 deletions src/com/phpuaca/completion/filter/MockBuilderFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,7 @@ public MockBuilderFilter(FilterContext context) {

ClassFinder.Result classFinderResult = (new ClassFinder()).find(methodReference);
if (classFinderResult != null) {
if (classFinderResult.getClassConstantReference() != null) {
setClassConstantReference(classFinderResult.getClassConstantReference());
}
if (classFinderResult.getClassName() != null) {
setClassName(classFinderResult.getClassName());
}
setPhpClass(classFinderResult.getPhpClass());
}

disallowMethod("__construct");
Expand Down
43 changes: 13 additions & 30 deletions src/com/phpuaca/completion/filter/util/ClassFinder.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.jetbrains.php.lang.psi.elements.*;
import com.phpuaca.completion.filter.FilterConfigItem;
import com.phpuaca.completion.filter.FilterFactory;
import com.phpuaca.completion.util.PhpClassResolver;
import com.phpuaca.completion.util.PhpMethodChain;
import com.phpuaca.completion.util.PhpVariable;
import org.jetbrains.annotations.NotNull;
Expand Down Expand Up @@ -33,26 +34,19 @@ public Result find(@NotNull MethodReference methodReference)
return null;
}

PhpClass phpClass = null;
ParameterList parameterList = mockBuilderMethodReference.getParameterList();
ClassConstantReference classConstantReference = PsiTreeUtil.getChildOfType(parameterList, ClassConstantReference.class);
if (classConstantReference != null) {
return new Result(classConstantReference, filterConfigItem.getParameterNumber());
}

StringLiteralExpression stringLiteral = PsiTreeUtil.getChildOfType(parameterList, StringLiteralExpression.class);
if (stringLiteral != null) {
String className = stringLiteral.getContents();

if (!className.isEmpty()) {
// \\ -> \
className = className.replace("\\\\", "\\");
if (!className.isEmpty()) {
return new Result(className, filterConfigItem.getParameterNumber());
}
phpClass = (new PhpClassResolver()).resolveByClassConstantReference(classConstantReference);
} else {
StringLiteralExpression stringLiteralExpression = PsiTreeUtil.getChildOfType(parameterList, StringLiteralExpression.class);
if (stringLiteralExpression != null) {
phpClass = (new PhpClassResolver()).resolveByClassStringLiteralExpression(stringLiteralExpression);
}
}

return null;
return phpClass == null ? null : new Result(phpClass, filterConfigItem.getParameterNumber());
}

@Nullable
Expand All @@ -63,34 +57,23 @@ public Result find(@NotNull Variable variable)
}

public class Result {
private ClassConstantReference classConstantReference;
private String className;
private PhpClass phpClass;
private int parameterNumber;

public Result(@NotNull ClassConstantReference classConstantReference, int parameterNumber)
public Result(@NotNull PhpClass phpClass, int parameterNumber)
{
this.classConstantReference = classConstantReference;
this.phpClass = phpClass;
this.parameterNumber = parameterNumber;
}

public Result(@NotNull String className, int parameterNumber)
public PhpClass getPhpClass()
{
this.className = className;
this.parameterNumber = parameterNumber;
}

public ClassConstantReference getClassConstantReference()
{
return classConstantReference;
return phpClass;
}

public int getParameterNumber()
{
return parameterNumber;
}

public String getClassName() {
return className;
}
}
}
26 changes: 5 additions & 21 deletions src/com/phpuaca/completion/provider/LookupElementProvider.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
package com.phpuaca.completion.provider;

import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.openapi.project.Project;
import com.jetbrains.php.completion.PhpLookupElement;
import com.jetbrains.php.lang.psi.elements.ClassConstantReference;
import com.jetbrains.php.lang.psi.elements.Field;
import com.jetbrains.php.lang.psi.elements.Method;
import com.jetbrains.php.lang.psi.elements.PhpClass;
import com.phpuaca.completion.filter.Filter;
import com.phpuaca.completion.util.PhpClassResolver;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
Expand All @@ -17,31 +14,18 @@
public class LookupElementProvider {

@NotNull
public List<LookupElement> find(@NotNull Project project, @NotNull Filter filter)
public List<LookupElement> find(@NotNull Filter filter)
{
List<LookupElement> list = new ArrayList<LookupElement>();
ClassConstantReference classConstantReference = filter.getClassConstantReference();
PhpClass resolvedClass = null;
PhpClass phpClass = filter.getPhpClass();

if (classConstantReference != null) {
PhpClassResolver resolver = new PhpClassResolver(classConstantReference);
if (resolver.resolve()) {
resolvedClass = resolver.getResolvedClass();
}
}

String className = filter.getClassName();
if (className != null) {
resolvedClass = PhpClassResolver.getClass(project, className);
}

if (resolvedClass != null) {
for (Method method : resolvedClass.getMethods()) {
if (phpClass != null) {
for (Method method : phpClass.getMethods()) {
if (filter.isMethodAllowed(method)) {
list.add(new PhpLookupElement(method));
}
}
for (Field field : resolvedClass.getFields()) {
for (Field field : phpClass.getFields()) {
if (!field.isConstant() && filter.isFieldAllowed(field)) {
list.add(new PhpLookupElement(field));
}
Expand Down
5 changes: 0 additions & 5 deletions src/com/phpuaca/completion/util/IResolver.java

This file was deleted.

55 changes: 20 additions & 35 deletions src/com/phpuaca/completion/util/PhpClassResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,59 +3,44 @@
import com.intellij.openapi.project.Project;
import com.intellij.psi.util.PsiTreeUtil;
import com.jetbrains.php.PhpIndex;
import com.jetbrains.php.lang.psi.elements.ClassConstantReference;
import com.jetbrains.php.lang.psi.elements.ClassReference;
import com.jetbrains.php.lang.psi.elements.PhpClass;
import com.jetbrains.php.lang.psi.elements.PhpNamedElement;
import com.jetbrains.php.lang.psi.elements.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;

final public class PhpClassResolver implements IResolver {
final public class PhpClassResolver {

private ClassReference classReference;
private PhpClass resolvedClass;

public PhpClassResolver(@NotNull ClassReference classReference)
{
this.classReference = classReference;
}

public PhpClassResolver(@NotNull ClassConstantReference classConstantReference)
{
this.classReference = PsiTreeUtil.getChildOfType(classConstantReference, ClassReference.class);
}

public boolean resolve()
@Nullable
public PhpClass resolveByClassConstantReference(@NotNull ClassConstantReference classConstantReference)
{
ClassReference classReference = PsiTreeUtil.getChildOfType(classConstantReference, ClassReference.class);
if (classReference != null) {
Collection<?extends PhpNamedElement> resolvedCollection = classReference.resolveGlobal(false);
Collection<? extends PhpNamedElement> resolvedCollection = classReference.resolveGlobal(false);
if (!resolvedCollection.isEmpty()) {
PhpNamedElement resolvedElement = resolvedCollection.iterator().next();
if (resolvedElement instanceof PhpClass) {
resolvedClass = (PhpClass) resolvedElement;
return true;
return (PhpClass) resolvedElement;
}
}
}

return false;
}

public PhpClass getResolvedClass()
{
return resolvedClass;
return null;
}

@Nullable
static public PhpClass getClass(Project project, String className) {
return getClass(PhpIndex.getInstance(project), className);
}
public PhpClass resolveByClassStringLiteralExpression(@NotNull StringLiteralExpression stringLiteralExpression)
{
String className = stringLiteralExpression.getContents();
if (!className.isEmpty()) {
className = className.replace("\\\\", "\\");
Project project = stringLiteralExpression.getProject();
Collection<PhpClass> phpClasses = PhpIndex.getInstance(project).getClassesByFQN(className);
if (!phpClasses.isEmpty()) {
return phpClasses.iterator().next();
}
}

@Nullable
static public PhpClass getClass(PhpIndex phpIndex, String className) {
Collection<PhpClass> classes = phpIndex.getClassesByFQN(className);
return classes.isEmpty() ? null : classes.iterator().next();
return null;
}
}
3 changes: 1 addition & 2 deletions src/com/phpuaca/completion/util/PhpMethodResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@

import java.util.Collection;

final public class PhpMethodResolver implements IResolver {
final public class PhpMethodResolver {

private MethodReference methodReference;
private Method resolvedMethod;
private PhpClass resolvedClass;


public PhpMethodResolver(@NotNull MethodReference methodReference)
{
this.methodReference = methodReference;
Expand Down

0 comments on commit 5992c73

Please sign in to comment.