use of com.intellij.dupLocator.iterators.FilteringNodeIterator in project intellij-community by JetBrains.
the class DuplicatesMatchingVisitor method match.
@Override
public boolean match(PsiElement element1, PsiElement element2) {
if (element1 == null || element2 == null) {
return element1 == element2;
}
if (myDiscardCost > 0) {
final int cost1 = myTreeHasher.hash(element1, null, myNodeSpecificHasher).getCost();
final int cost2 = myTreeHasher.hash(element2, null, myNodeSpecificHasher).getCost();
if (cost1 < myDiscardCost || cost2 < myDiscardCost) {
return true;
}
}
final DuplicatesProfileBase duplicatesProfile = myNodeSpecificHasher.getDuplicatesProfile();
final PsiElementRole role1 = duplicatesProfile.getRole(element1);
final PsiElementRole role2 = duplicatesProfile.getRole(element2);
final Set<PsiElementRole> skippedRoles = EnumSet.noneOf(PsiElementRole.class);
final ExternalizableDuplocatorState duplocatorState = duplicatesProfile.getDuplocatorState(duplicatesProfile.getLanguage(element1));
for (PsiElementRole role : PsiElementRole.values()) {
if (!duplocatorState.distinguishRole(role)) {
skippedRoles.add(role);
}
}
if (role1 == role2 && skippedRoles.contains(role1)) {
return true;
}
final EquivalenceDescriptorProvider descriptorProvider = EquivalenceDescriptorProvider.getInstance(element1);
EquivalenceDescriptor descriptor1 = descriptorProvider != null ? descriptorProvider.buildDescriptor(element1) : null;
EquivalenceDescriptor descriptor2 = descriptorProvider != null ? descriptorProvider.buildDescriptor(element2) : null;
PsiElement newElement1 = DuplocatorUtil.skipNodeIfNeccessary(element1, descriptor1, myNodeFilter);
PsiElement newElement2 = DuplocatorUtil.skipNodeIfNeccessary(element2, descriptor2, myNodeFilter);
if (newElement1 != element1 || newElement2 != element2) {
return match(newElement1, newElement2);
}
if (!element1.getClass().equals(element2.getClass())) {
return false;
}
if (descriptor1 != null && descriptor2 != null) {
return DuplocatorUtil.match(descriptor1, descriptor2, this, skippedRoles, duplicatesProfile);
}
if (element1 instanceof LeafElement) {
IElementType elementType1 = ((LeafElement) element1).getElementType();
IElementType elementType2 = ((LeafElement) element2).getElementType();
if (!duplocatorState.distinguishLiterals() && duplicatesProfile.getLiterals().contains(elementType1) && duplicatesProfile.getLiterals().contains(elementType2)) {
return true;
}
return element1.getText().equals(element2.getText());
}
if (element1.getFirstChild() == null && element1.getTextLength() == 0) {
return element2.getFirstChild() == null && element2.getTextLength() == 0;
}
return matchSequentially(new FilteringNodeIterator(new SiblingNodeIterator(element1.getFirstChild()), getNodeFilter()), new FilteringNodeIterator(new SiblingNodeIterator(element2.getFirstChild()), getNodeFilter()));
}
use of com.intellij.dupLocator.iterators.FilteringNodeIterator in project intellij-community by JetBrains.
the class AbstractMatchingVisitor method matchSonsInAnyOrder.
public final boolean matchSonsInAnyOrder(PsiElement element1, PsiElement element2) {
if (element1 == null && isLeftLooseMatching()) {
return true;
}
if (element2 == null && isRightLooseMatching()) {
return true;
}
if (element1 == null || element2 == null) {
return element1 == element2;
}
PsiElement e = element1.getFirstChild();
PsiElement e2 = element2.getFirstChild();
return (e == null && isLeftLooseMatching()) || (e2 == null && isRightLooseMatching()) || matchInAnyOrder(new FilteringNodeIterator(new SiblingNodeIterator(e), getNodeFilter()), new FilteringNodeIterator(new SiblingNodeIterator(e2), getNodeFilter()));
}
use of com.intellij.dupLocator.iterators.FilteringNodeIterator in project intellij-community by JetBrains.
the class NodeSpecificHasherBase method getNodeChildren.
@Override
public List<PsiElement> getNodeChildren(PsiElement node) {
final List<PsiElement> result = new ArrayList<>();
final FilteringNodeIterator it = new FilteringNodeIterator(new SiblingNodeIterator(node.getFirstChild()), myNodeFilter);
while (it.hasNext()) {
result.add(it.current());
it.advance();
}
return result;
}
use of com.intellij.dupLocator.iterators.FilteringNodeIterator in project intellij-community by JetBrains.
the class DuplocatorUtil method getOnlyChild.
public static PsiElement getOnlyChild(PsiElement element, @NotNull NodeFilter filter) {
FilteringNodeIterator it = new FilteringNodeIterator(new SiblingNodeIterator(element.getFirstChild()), filter);
PsiElement child = it.current();
if (child != null) {
it.advance();
if (!it.hasNext()) {
return child;
}
}
return element;
}
use of com.intellij.dupLocator.iterators.FilteringNodeIterator in project intellij-community by JetBrains.
the class SubstitutionHandler method doMatchSequentially.
protected boolean doMatchSequentially(NodeIterator nodes, NodeIterator nodes2, MatchContext context) {
final int previousMatchedOccurs = matchedOccurs;
FilteringNodeIterator fNodes2 = new FilteringNodeIterator(nodes2, VARS_DELIM_FILTER);
try {
MatchingHandler handler = context.getPattern().getHandler(nodes.current());
matchedOccurs = 0;
boolean flag = false;
while (fNodes2.hasNext() && matchedOccurs < minOccurs) {
if (handler.match(nodes.current(), nodes2.current(), context)) {
++matchedOccurs;
} else {
break;
}
fNodes2.advance();
flag = true;
}
if (matchedOccurs != minOccurs) {
// failed even for min occurs
removeLastResults(matchedOccurs, context);
fNodes2.rewind(matchedOccurs);
return false;
}
if (greedy) {
while (fNodes2.hasNext() && matchedOccurs < maxOccurs) {
if (handler.match(nodes.current(), nodes2.current(), context)) {
++matchedOccurs;
} else {
// no more matches could take!
break;
}
fNodes2.advance();
flag = true;
}
if (flag) {
fNodes2.rewind();
nodes2.advance();
}
nodes.advance();
if (nodes.hasNext()) {
final MatchingHandler nextHandler = context.getPattern().getHandler(nodes.current());
while (matchedOccurs >= minOccurs) {
if (nextHandler.matchSequentially(nodes, nodes2, context)) {
totalMatchedOccurs = matchedOccurs;
// match found
return true;
}
if (matchedOccurs > 0) {
nodes2.rewind();
removeLastResults(1, context);
}
--matchedOccurs;
}
if (matchedOccurs > 0) {
removeLastResults(matchedOccurs, context);
}
nodes.rewind();
return false;
} else {
// match found
if (handler.isMatchSequentiallySucceeded(nodes2)) {
return checkSameOccurrencesConstraint();
}
removeLastResults(matchedOccurs, context);
return false;
}
} else {
nodes.advance();
if (flag) {
fNodes2.rewind();
nodes2.advance();
}
if (nodes.hasNext()) {
final MatchingHandler nextHandler = context.getPattern().getHandler(nodes.current());
flag = false;
while (nodes2.hasNext() && matchedOccurs <= maxOccurs) {
if (nextHandler.matchSequentially(nodes, nodes2, context)) {
return checkSameOccurrencesConstraint();
}
if (flag) {
nodes2.rewind();
fNodes2.advance();
}
if (handler.match(nodes.current(), nodes2.current(), context)) {
matchedOccurs++;
} else {
nodes.rewind();
removeLastResults(matchedOccurs, context);
return false;
}
nodes2.advance();
flag = true;
}
nodes.rewind();
removeLastResults(matchedOccurs, context);
return false;
} else {
return checkSameOccurrencesConstraint();
}
}
} finally {
matchedOccurs = previousMatchedOccurs;
}
}
Aggregations