1/*******************************************************************************
2 * Copyright (c) 2009, 2015 Mountainminds GmbH & Co. KG and Contributors
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 *    Marc R. Hoffmann - initial API and implementation
10 *
11 *******************************************************************************/
12package org.jacoco.core.internal.flow;
13
14import org.jacoco.core.JaCoCo;
15import org.objectweb.asm.Label;
16import org.objectweb.asm.MethodVisitor;
17import org.objectweb.asm.commons.JSRInlinerAdapter;
18
19/**
20 * This method visitor fixes two potential issues with Java byte code:
21 *
22 * <ul>
23 * <li>Remove JSR/RET instructions by inlining subroutines which are deprecated
24 * since Java 6. The RET statement complicates control flow analysis as the jump
25 * target is not explicitly given.</li>
26 * <li>Remove code attributes line number and local variable name if they point
27 * to invalid offsets which some tools create. When writing out such invalid
28 * labels with ASM class files do not verify any more.</li>
29 * </ul>
30 */
31class MethodSanitizer extends JSRInlinerAdapter {
32
33	MethodSanitizer(final MethodVisitor mv, final int access,
34			final String name, final String desc, final String signature,
35			final String[] exceptions) {
36		super(JaCoCo.ASM_API_VERSION, mv, access, name, desc, signature,
37				exceptions);
38	}
39
40	@Override
41	public void visitLocalVariable(final String name, final String desc,
42			final String signature, final Label start, final Label end,
43			final int index) {
44		// Here we rely on the usage of the info fields by the tree API. If the
45		// labels have been properly used before the info field contains a
46		// reference to the LabelNode, otherwise null.
47		if (start.info != null && end.info != null) {
48			super.visitLocalVariable(name, desc, signature, start, end, index);
49		}
50	}
51
52	@Override
53	public void visitLineNumber(final int line, final Label start) {
54		// Here we rely on the usage of the info fields by the tree API. If the
55		// labels have been properly used before the info field contains a
56		// reference to the LabelNode, otherwise null.
57		if (start.info != null) {
58			super.visitLineNumber(line, start);
59		}
60	}
61
62}
63