mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
SSR: find expression statement with type (IDEA-171214)
This commit is contained in:
+26
-15
@@ -1,3 +1,18 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.structuralsearch.impl.matcher.handlers;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
@@ -8,25 +23,21 @@ import com.intellij.structuralsearch.impl.matcher.MatchContext;
|
||||
*/
|
||||
public class StatementHandler extends MatchingHandler {
|
||||
|
||||
@Override
|
||||
public boolean match(PsiElement patternNode, PsiElement matchedNode, MatchContext context) {
|
||||
// filtering is done on SubstituionHandler level
|
||||
if (patternNode==null) return false;
|
||||
patternNode = ((PsiExpressionStatement)patternNode).getExpression();
|
||||
// filtering is done on SubstitutionHandler level
|
||||
if (patternNode == null) return false;
|
||||
|
||||
/*if (matchedNode instanceof PsiExpressionStatement) {
|
||||
//matchedNode = ((PsiExpressionStatement)matchedNode).getExpression();
|
||||
} else*/ if (( !(matchedNode instanceof PsiStatement) &&
|
||||
!(matchedNode instanceof PsiComment) // comments to be matched as statements
|
||||
) ||
|
||||
( matchedNode instanceof PsiBlockStatement &&
|
||||
!(matchedNode.getParent() instanceof PsiBlockStatement) &&
|
||||
!(matchedNode.getParent().getParent() instanceof PsiSwitchStatement)
|
||||
)) {
|
||||
// typed statement does not match this things
|
||||
// (BlockStatement could be nontop level in if, etc)
|
||||
if ((!(matchedNode instanceof PsiStatement) && !(matchedNode instanceof PsiComment) /* comments are matched as statements */) ||
|
||||
(matchedNode instanceof PsiBlockStatement &&
|
||||
!(matchedNode.getParent() instanceof PsiBlockStatement) &&
|
||||
!(matchedNode.getParent().getParent() instanceof PsiSwitchStatement))) {
|
||||
// typed statement does not match these things
|
||||
// (BlockStatement could be non-top level in if, etc)
|
||||
return false;
|
||||
}
|
||||
|
||||
return context.getMatcher().match(patternNode,matchedNode);
|
||||
patternNode = ((PsiExpressionStatement)patternNode).getExpression();
|
||||
return context.getMatcher().match(patternNode, matchedNode);
|
||||
}
|
||||
}
|
||||
|
||||
+38
-26
@@ -1,3 +1,18 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.structuralsearch.impl.matcher.predicates;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
@@ -7,52 +22,49 @@ import com.intellij.structuralsearch.impl.matcher.iterators.HierarchyNodeIterato
|
||||
import com.intellij.dupLocator.iterators.NodeIterator;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: Maxim.Mossienko
|
||||
* @author Maxim.Mossienko
|
||||
* Date: Mar 23, 2004
|
||||
* Time: 6:37:15 PM
|
||||
* To change this template use File | Settings | File Templates.
|
||||
*/
|
||||
public class ExprTypePredicate extends MatchPredicate {
|
||||
private final RegExpPredicate delegate;
|
||||
private final boolean withinHierarchy;
|
||||
|
||||
public ExprTypePredicate(String type, String baseName, boolean _withinHierarchy, boolean caseSensitiveMatch,boolean target) {
|
||||
delegate = new RegExpPredicate(type,caseSensitiveMatch,baseName,false,target);
|
||||
public ExprTypePredicate(String type, String baseName, boolean _withinHierarchy, boolean caseSensitiveMatch, boolean target) {
|
||||
delegate = new RegExpPredicate(type, caseSensitiveMatch, baseName, false, target);
|
||||
withinHierarchy = _withinHierarchy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean match(PsiElement patternNode, PsiElement matchedNode, MatchContext context) {
|
||||
return match(patternNode, matchedNode, 0, -1, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean match(PsiElement node, PsiElement match, int start, int end, MatchContext context) {
|
||||
if (match instanceof PsiIdentifier) {
|
||||
// since we pickup tokens
|
||||
match = match.getParent();
|
||||
}
|
||||
else if (match instanceof PsiExpressionStatement) {
|
||||
match = ((PsiExpressionStatement)match).getExpression();
|
||||
}
|
||||
|
||||
if (match instanceof PsiExpression) {
|
||||
final PsiType type = evalType((PsiExpression)match,context);
|
||||
if (type==null) return false;
|
||||
|
||||
return doMatchWithTheType(type, context, match);
|
||||
} else {
|
||||
if (!(match instanceof PsiExpression)) {
|
||||
return false;
|
||||
}
|
||||
final PsiType type = evalType((PsiExpression)match, context);
|
||||
return type != null && doMatchWithTheType(type, context, match);
|
||||
}
|
||||
|
||||
protected PsiType evalType(PsiExpression match, MatchContext context) {
|
||||
PsiType type = null;
|
||||
|
||||
if (match instanceof PsiReferenceExpression &&
|
||||
match.getParent() instanceof PsiMethodCallExpression) {
|
||||
PsiMethod method = ((PsiMethodCallExpression)match.getParent()).resolveMethod();
|
||||
if (method!=null) type = method.getReturnType();
|
||||
if (match instanceof PsiReferenceExpression) {
|
||||
final PsiElement parent = match.getParent();
|
||||
if (parent instanceof PsiMethodCallExpression) {
|
||||
return ((PsiMethodCallExpression)parent).getType();
|
||||
}
|
||||
}
|
||||
|
||||
if (type==null) type = match.getType();
|
||||
return type;
|
||||
return match.getType();
|
||||
}
|
||||
|
||||
private boolean doMatchWithTheType(final PsiType type, MatchContext context, PsiElement matchedNode) {
|
||||
@@ -64,13 +76,13 @@ public class ExprTypePredicate extends MatchPredicate {
|
||||
|
||||
if (type!=null) {
|
||||
final String presentableText = type.getPresentableText();
|
||||
boolean result = delegate.doMatch(presentableText,context, matchedNode);
|
||||
boolean result = delegate.doMatch(presentableText, context, matchedNode);
|
||||
|
||||
if (!result && type instanceof PsiArrayType && ((PsiArrayType)type).getComponentType() instanceof PsiClassType) {
|
||||
PsiClass clazz = ((PsiClassType)((PsiArrayType)type).getComponentType()).resolve();
|
||||
|
||||
if (clazz!=null) { // presentable text for array is not qualified!
|
||||
result = delegate.doMatch(clazz.getQualifiedName()+"[]",context, matchedNode);
|
||||
result = delegate.doMatch(clazz.getQualifiedName() + "[]", context, matchedNode);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -79,17 +91,17 @@ public class ExprTypePredicate extends MatchPredicate {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean checkClass(PsiClass clazz, MatchContext context) {
|
||||
private boolean checkClass(PsiClass clazz, MatchContext context) {
|
||||
if (withinHierarchy) {
|
||||
final NodeIterator parents = new HierarchyNodeIterator(clazz,true,true);
|
||||
final NodeIterator parents = new HierarchyNodeIterator(clazz, true, true);
|
||||
|
||||
while(parents.hasNext() && !delegate.match(null,parents.current(),context)) {
|
||||
while(parents.hasNext() && !delegate.match(null, parents.current(), context)) {
|
||||
parents.advance();
|
||||
}
|
||||
|
||||
return parents.hasNext();
|
||||
} else {
|
||||
return delegate.match(null,clazz,context);
|
||||
return delegate.match(null, clazz, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
@@ -600,6 +600,10 @@ public class StructuralSearchTest extends StructuralSearchTestCase {
|
||||
" }" +
|
||||
"}";
|
||||
assertEquals("Should find statements and comments in statement context only", 2, findMatchesCount(in2, "'_statement;"));
|
||||
|
||||
String in3 = "new Object().hashCode();" +
|
||||
"new Object().toString();";
|
||||
assertEquals("Find typed expression statements", 1, findMatchesCount(in3, "'_expr:[exprtype( int )];"));
|
||||
}
|
||||
|
||||
public void testSearchClass() {
|
||||
|
||||
Reference in New Issue
Block a user