diff options
Diffstat (limited to 'org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/AbstractMatcher.java')
-rw-r--r-- | org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/AbstractMatcher.java | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/AbstractMatcher.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/AbstractMatcher.java new file mode 100644 index 00000000..e4958bdb --- /dev/null +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/AbstractMatcher.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2009, 2017 Mountainminds GmbH & Co. KG and Contributors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Evgeny Mandrikov - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.core.internal.analysis.filter; + +import java.util.HashMap; +import java.util.Map; + +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.tree.AbstractInsnNode; +import org.objectweb.asm.tree.MethodInsnNode; +import org.objectweb.asm.tree.VarInsnNode; + +abstract class AbstractMatcher { + + final Map<String, VarInsnNode> vars = new HashMap<String, VarInsnNode>(); + + AbstractInsnNode cursor; + + final void nextIsAddSuppressed() { + nextIs(Opcodes.INVOKEVIRTUAL); + if (cursor == null) { + return; + } + final MethodInsnNode m = (MethodInsnNode) cursor; + if ("java/lang/Throwable".equals(m.owner) + && "addSuppressed".equals(m.name)) { + return; + } + cursor = null; + } + + final void nextIsVar(final int opcode, final String name) { + nextIs(opcode); + if (cursor == null) { + return; + } + final VarInsnNode actual = (VarInsnNode) cursor; + final VarInsnNode expected = vars.get(name); + if (expected == null) { + vars.put(name, actual); + } else if (expected.var != actual.var) { + cursor = null; + } + } + + /** + * Moves {@link #cursor} to next instruction if it has given opcode, + * otherwise sets it to <code>null</code>. + */ + final void nextIs(final int opcode) { + next(); + if (cursor == null) { + return; + } + if (cursor.getOpcode() != opcode) { + cursor = null; + } + } + + /** + * Moves {@link #cursor} to next instruction. + */ + final void next() { + if (cursor == null) { + return; + } + do { + cursor = cursor.getNext(); + } while (cursor != null && (cursor.getType() == AbstractInsnNode.FRAME + || cursor.getType() == AbstractInsnNode.LABEL + || cursor.getType() == AbstractInsnNode.LINE)); + } + +} |