SSR: expand search for "formal argument type of the method" to expected type

This commit is contained in:
Bas Leijdekkers
2015-01-06 14:45:32 +01:00
parent 7432a4307c
commit 28653758fd
4 changed files with 24 additions and 26 deletions
@@ -286,10 +286,12 @@ class JavaPredefinedConfigurations {
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.fields.variables.read"),"'Symbol:[read]",INTERESTING_TYPE),
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.fields_variables.with.given.name.pattern.updated"),"'Symbol:[regex( name ) && write]",INTERESTING_TYPE),
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.usage.of.derived.type.in.cast"),"('CastType:*Base ) 'Expr",INTERESTING_TYPE),
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.boxing.in.declarations"),"'_Type:Integer|Boolean|Long|Character|Short|Byte 'Var = '_Value:[formal( int|boolean|long|char|short|byte )]",INTERESTING_TYPE),
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.unboxing.in.declarations"),"'_Type:int|boolean|long|char|short|byte 'Var = '_Value:[formal( Integer|Boolean|Long|Character|Short|Byte )]",INTERESTING_TYPE),
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.boxing.in.method.calls"),"'_Instance?.'Call('_BeforeParam*,'_Param:[ exprtype( int|boolean|long|char|short|byte ) && formal( Integer|Boolean|Long|Character|Short|Byte )],'_AfterParam*)",INTERESTING_TYPE),
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.boxing.in.declarations"),"'_Type:Object|Integer|Boolean|Long|Character|Short|Byte 'Var = '_Value:[exprtype( int|boolean|long|char|short|byte )]",INTERESTING_TYPE),
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.unboxing.in.declarations"),"'_Type:int|boolean|long|char|short|byte 'Var = '_Value:[exprtype( Integer|Boolean|Long|Character|Short|Byte )]",INTERESTING_TYPE),
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.boxing.in.method.calls"),"'_Instance?.'Call('_BeforeParam*,'_Param:[ exprtype( int|boolean|long|char|short|byte ) && formal( Object|Integer|Boolean|Long|Character|Short|Byte )],'_AfterParam*)",INTERESTING_TYPE),
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.unboxing.in.method.calls"), "'_Instance?.'Call('_BeforeParam*,'_Param:[ formal( int|boolean|long|char|short|byte ) && exprtype( Integer|Boolean|Long|Character|Short|Byte )],'_AfterParam*)",INTERESTING_TYPE),
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.any.boxing"), "'_expression:[ exprtype( int|boolean|long|char|short|byte ) && formal( Object|Integer|Boolean|Long|Character|Short|Byte )]", INTERESTING_TYPE),
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.any.unboxing"), "'_expression:[ formal( int|boolean|long|char|short|byte ) && exprtype( Integer|Boolean|Long|Character|Short|Byte )]", INTERESTING_TYPE),
//createSearchTemplateInfo("methods called","'_?.'_:[ref('Method)] ('_*)", INTERESTING_TYPE),
//createSearchTemplateInfo("fields selected","'_?.'_:[ref('Field)] ", INTERESTING_TYPE),
//createSearchTemplateInfo("symbols used","'_:[ref('Symbol)] ", INTERESTING_TYPE),
@@ -1,8 +1,9 @@
package com.intellij.structuralsearch.impl.matcher.predicates;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiType;
import com.intellij.structuralsearch.impl.matcher.MatchContext;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.siyeh.ig.psiutils.ExpectedTypeUtils;
/**
* Created by IntelliJ IDEA.
@@ -13,26 +14,11 @@ import com.intellij.psi.util.PsiTreeUtil;
*/
public class FormalArgTypePredicate extends ExprTypePredicate {
public FormalArgTypePredicate(String type, String baseName, boolean _withinHierarchy, boolean caseSensitiveMatch,boolean target) {
super(type, baseName, _withinHierarchy, caseSensitiveMatch, target);
public FormalArgTypePredicate(String type, String baseName, boolean withinHierarchy, boolean caseSensitiveMatch, boolean target) {
super(type, baseName, withinHierarchy, caseSensitiveMatch, target);
}
protected PsiType evalType(PsiExpression match, MatchContext context) {
final PsiMethodCallExpression expr = PsiTreeUtil.getParentOfType(match,PsiMethodCallExpression.class);
if (expr == null) return null;
// find our parent in parameters of the method
final PsiMethod psiMethod = expr.resolveMethod();
if (psiMethod == null) return null;
final PsiParameter[] methodParameters = psiMethod.getParameterList().getParameters();
final PsiExpression[] expressions = expr.getArgumentList().getExpressions();
for(int i = 0;i < methodParameters.length; ++i) {
if (expressions[i] == match) {
if (i < methodParameters.length) return methodParameters[i].getType();
break;
}
}
return null;
return ExpectedTypeUtils.findExpectedType(match, true, true);
}
}
@@ -86,6 +86,8 @@ predefined.configuration.unboxing.in.method.calls=unboxing in method calls
predefined.configuration.boxing.in.method.calls=boxing in method calls
predefined.configuration.unboxing.in.declarations=unboxing in declarations
predefined.configuration.boxing.in.declarations=boxing in declarations
predefined.configuration.any.unboxing=unboxed expressions
predefined.configuration.any.boxing=boxed expressions
predefined.configuration.filters=filters
predefined.configuration.session.ejb=session ejb
predefined.configuration.fields.variables.read=fields/variables read
@@ -158,8 +160,8 @@ editvarcontraints.maximum.count=Maximum count\:
editvarcontraints.minimum.count=Minimum count\:
editvarcontraints.apply.constraint.within.type.hierarchy=Apply constraint within type hierarchy
editvarcontraints.invert.condition=Invert condition
editvarcontraints.text.regular.expression.for.formal.argument.type.of.the.method=Text/regexp for formal argument type of the method\:
editvarcontraints.text.regular.expression.for.java.expression.type=Text/regexp for java expression type\:
editvarcontraints.text.regular.expression.for.formal.argument.type.of.the.method=Expected type of expression (regexp)\:
editvarcontraints.text.regular.expression.for.java.expression.type=Expression type (regexp)\:
editvarcontraints.value.is.written=Value is written
editvarcontraints.value.is.read=Value is read
editvarcontraints.whole.words.only=Whole words only
@@ -2464,12 +2464,20 @@ public class StructuralSearchTest extends StructuralSearchTestCase {
"a.c(new Integer(2));\n" +
"a.c(new Integer(3));\n" +
"a.c2(new Integer(3));\n" +
"a.c(3);";
"a.c(3);\n" +
"Integer i = 4;\n" +
"int j = Integer.valueOf(4);\n";
String s2 = "a.'b('_Params:[formal( Integer ) && exprtype( int ) ])";
String s2_2 = "a.c('_Params:[formal( int ) && exprtype( Integer ) ])";
assertEquals("Find boxing in method call",1,findMatchesCount(s1,s2,false));
assertEquals("Find unboxing in method call",2,findMatchesCount(s1,s2_2,false));
String pattern1 = "'_a:[formal( Integer ) && exprtype( int ) ]";
assertEquals("Find any boxing", 2, findMatchesCount(s1, pattern1));
String pattern2 = "'_a:[formal( int ) && exprtype( Integer ) ]";
assertEquals("Find any unboxing", 3, findMatchesCount(s1, pattern2));
}
public void testCommentsInDclSearch() {