com.strobel.decompiler.patterns.Repeat Maven / Gradle / Ivy
/*
* Repeat.java
*
* Copyright (c) 2013 Mike Strobel
*
* This source code is based on Mono.Cecil from Jb Evain, Copyright (c) Jb Evain;
* and ILSpy/ICSharpCode from SharpDevelop, Copyright (c) AlphaSierraPapa.
*
* This source code is subject to terms and conditions of the Apache License, Version 2.0.
* A copy of the license can be found in the License.html file at the root of this distribution.
* By using this source code in any fashion, you are agreeing to be bound by the terms of the
* Apache License, Version 2.0.
*
* You must not remove this notice, or any other, from this software.
*/
package com.strobel.decompiler.patterns;
import com.strobel.core.VerifyArgument;
import java.util.Stack;
public final class Repeat extends Pattern {
private final INode _node;
private int _minCount;
private int _maxCount;
public Repeat(final INode node) {
_node = VerifyArgument.notNull(node, "node");
_minCount = 0;
_maxCount = Integer.MAX_VALUE;
}
public final INode getNode() {
return _node;
}
public final int getMinCount() {
return _minCount;
}
public final void setMinCount(final int minCount) {
_minCount = minCount;
}
public final int getMaxCount() {
return _maxCount;
}
public final void setMaxCount(final int maxCount) {
_maxCount = maxCount;
}
@Override
public final boolean matchesCollection(
final Role role,
final INode position,
final Match match,
final BacktrackingInfo backtrackingInfo) {
final Stack backtrackingStack = backtrackingInfo.stack;
assert position == null || position.getRole() == role;
int matchCount = 0;
INode current = position;
if (_minCount <= 0)
backtrackingStack.push(new PossibleMatch(current, match.getCheckPoint()));
while (matchCount < _maxCount &&
current != null &&
_node.matches(current, match)) {
matchCount++;
do {
current = current.getNextSibling();
} while (current != null && current.getRole() != role);
if (matchCount >= _minCount) {
backtrackingStack.push(new PossibleMatch(current, match.getCheckPoint()));
}
}
//
// Never do a single-element match; always make the caller look at the results on the
// back-tracking stack.
//
return false;
}
@Override
public boolean matches(final INode other, final Match match) {
if (other == null || other.isNull()) {
return _minCount <= 0;
}
return _maxCount >= 1 && _node.matches(other, match);
}
}