1/*
2 * Copyright 2015, Google Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 *     * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *     * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 *     * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32package org.jf.smalidea;
33
34import com.intellij.testFramework.ResolveTestCase;
35import org.jf.dexlib2.Opcode;
36import org.jf.smalidea.psi.impl.SmaliInstruction;
37import org.jf.smalidea.psi.impl.SmaliLabel;
38import org.jf.smalidea.psi.impl.SmaliLabelReference;
39import org.junit.Assert;
40
41public class SmaliLabelReferenceTest extends ResolveTestCase {
42
43    public void testLabelReference() throws Exception {
44        String text =
45                ".class public Lmy/pkg/blah; .super Ljava/lang/Object;\n" +
46                        ".method public getRandomParentType(I)I\n" +
47                        "    .registers 4\n" +
48                        "    .param p1, \"edge\"    # I\n" +
49                        "\n" +
50                        "    .prologue\n" +
51                        "    const/4 v1, 0x2\n" +
52                        "\n" +
53                        "    .line 179\n" +
54                        "    if-nez p1, :cond_5\n" +
55                        "\n" +
56                        "    move v0, v1\n" +
57                        "\n" +
58                        "    .line 185\n" +
59                        "    :goto_4\n" +
60                        "    return v0\n" +
61                        "\n" +
62                        "    .line 182\n" +
63                        "    :cond_5\n" +
64                        "    if-ne p1, v1, :cond_f\n" +
65                        "\n" +
66                        "    .line 183\n" +
67                        "    sget-object v0, Lorg/jf/Penroser/PenroserApp;->random:Ljava/util/Random;\n" +
68                        "\n" +
69                        "    const/4 v1, 0x3\n" +
70                        "\n" +
71                        "    invoke-virtual {v0, v1}, Ljava/util/Random;->nextInt(I)I\n" +
72                        "\n" +
73                        "    move-result v0\n" +
74                        "\n" +
75                        "    goto :goto_4\n" +
76                        "\n" +
77                        "    .line 185\n" +
78                        "    :cond_f\n" +
79                        "    sget-object v0, Lorg/jf/Penroser/PenroserApp;->random:Ljava/util/Random;\n" +
80                        "\n" +
81                        "    invoke-virtual {v0, v1}, Ljava/util/Random;->nextInt(I)I\n" +
82                        "\n" +
83                        "    move-result v0\n" +
84                        "\n" +
85                        "    goto :go<ref>to_4\n" +
86                        ".end method";;
87
88        SmaliLabelReference labelReference = (SmaliLabelReference)configureByFileText(text, "blah.smali");
89
90        Assert.assertNotNull(labelReference);
91        Assert.assertEquals("goto_4", labelReference.getName());
92
93        SmaliLabel resolvedLabel = labelReference.resolve();
94        Assert.assertNotNull(resolvedLabel);
95        Assert.assertEquals("goto_4", resolvedLabel.getName());
96
97        SmaliInstruction nextInstruction = resolvedLabel.findNextSiblingByClass(SmaliInstruction.class);
98        Assert.assertNotNull(nextInstruction);
99        Assert.assertEquals(8, nextInstruction.getOffset());
100        Assert.assertEquals(Opcode.RETURN, nextInstruction.getOpcode());
101    }
102}
103