Implement some of the initial .register and register reference stuff

This commit is contained in:
Ben Gruver 2014-03-29 10:47:30 -07:00
parent 3048a6c897
commit 12b3579577
10 changed files with 389 additions and 32 deletions

View File

@ -287,7 +287,7 @@ simple_name
| DOUBLE_LITERAL_OR_ID
| BOOL_LITERAL
| NULL_LITERAL
| REGISTER
| register
| param_list_or_id
| PRIMITIVE_TYPE
| VOID_TYPE
@ -536,11 +536,11 @@ label_ref
finally { marker.done(SmaliElementTypes.LABEL_REFERENCE); }
register_list
: REGISTER (COMMA REGISTER)*
: register (COMMA register)*
| /* epsilon */;
register_range
: (REGISTER (DOTDOT REGISTER)?)?;
: (register (DOTDOT register)?)?;
verification_error_reference
: class_descriptor | fully_qualified_field | fully_qualified_method;
@ -560,12 +560,17 @@ or method annotations until we determine if there is an .end parameter directive
the annotations. If it turns out that they are parameter annotations, we include them in the I_PARAMETER AST. Otherwise, we
add them to the $statements_and_directives::methodAnnotations list*/
parameter_directive
: PARAMETER_DIRECTIVE REGISTER (COMMA string_literal)?
: PARAMETER_DIRECTIVE register (COMMA string_literal)?
({input.LA(1) == ANNOTATION_DIRECTIVE}? annotation)*
( END_PARAMETER_DIRECTIVE
| /*epsilon*/
);
register
@init { Marker marker = mark(); }
: REGISTER;
finally { marker.done(SmaliElementTypes.REGISTER_REFERENCE); }
debug_directive
: line_directive
| local_directive
@ -582,18 +587,18 @@ line_directive
local_directive
@init { Marker marker = mark(); }
: LOCAL_DIRECTIVE REGISTER (COMMA (null_literal | string_literal) COLON (void_type | nonvoid_type_descriptor)
: LOCAL_DIRECTIVE register (COMMA (null_literal | string_literal) COLON (void_type | nonvoid_type_descriptor)
(COMMA string_literal)? )?;
finally { marker.done(SmaliElementTypes.LOCAL_DEBUG_STATEMENT); }
end_local_directive
@init { Marker marker = mark(); }
: END_LOCAL_DIRECTIVE REGISTER;
: END_LOCAL_DIRECTIVE register;
finally { marker.done(SmaliElementTypes.END_LOCAL_DEBUG_STATEMENT); }
restart_local_directive
@init { Marker marker = mark(); }
: RESTART_LOCAL_DIRECTIVE REGISTER;
: RESTART_LOCAL_DIRECTIVE register;
finally { marker.done(SmaliElementTypes.RESTART_LOCAL_DEBUG_STATEMENT); }
prologue_directive
@ -686,15 +691,15 @@ insn_format10x_odex
insn_format11n
: //e.g. const/4 v0, 5
INSTRUCTION_FORMAT11n REGISTER COMMA integral_literal;
INSTRUCTION_FORMAT11n register COMMA integral_literal;
insn_format11x
: //e.g. move-result-object v1
INSTRUCTION_FORMAT11x REGISTER;
INSTRUCTION_FORMAT11x register;
insn_format12x
: //e.g. move v1 v2
instruction_format12x REGISTER COMMA REGISTER;
instruction_format12x register COMMA register;
insn_format20bc
: //e.g. throw-verification-error generic-error, Lsome/class;
@ -706,71 +711,71 @@ insn_format20t
insn_format21c_field
: //e.g. sget-object v0, java/lang/System/out LJava/io/PrintStream;
INSTRUCTION_FORMAT21c_FIELD REGISTER COMMA fully_qualified_field;
INSTRUCTION_FORMAT21c_FIELD register COMMA fully_qualified_field;
insn_format21c_field_odex
: //e.g. sget-object-volatile v0, java/lang/System/out LJava/io/PrintStream;
INSTRUCTION_FORMAT21c_FIELD_ODEX REGISTER COMMA fully_qualified_field;
INSTRUCTION_FORMAT21c_FIELD_ODEX register COMMA fully_qualified_field;
insn_format21c_string
: //e.g. const-string v1, "Hello World!"
INSTRUCTION_FORMAT21c_STRING REGISTER COMMA string_literal;
INSTRUCTION_FORMAT21c_STRING register COMMA string_literal;
insn_format21c_type
: //e.g. const-class v2, Lorg/jf/HelloWorld2/HelloWorld2;
INSTRUCTION_FORMAT21c_TYPE REGISTER COMMA nonvoid_type_descriptor;
INSTRUCTION_FORMAT21c_TYPE register COMMA nonvoid_type_descriptor;
insn_format21ih
: //e.g. const/high16 v1, 1234
INSTRUCTION_FORMAT21ih REGISTER COMMA fixed_32bit_literal;
INSTRUCTION_FORMAT21ih register COMMA fixed_32bit_literal;
insn_format21lh
: //e.g. const-wide/high16 v1, 1234
INSTRUCTION_FORMAT21lh REGISTER COMMA fixed_32bit_literal;
INSTRUCTION_FORMAT21lh register COMMA fixed_32bit_literal;
insn_format21s
: //e.g. const/16 v1, 1234
INSTRUCTION_FORMAT21s REGISTER COMMA integral_literal;
INSTRUCTION_FORMAT21s register COMMA integral_literal;
insn_format21t
: //e.g. if-eqz v0, endloop:
INSTRUCTION_FORMAT21t REGISTER COMMA label_ref;
INSTRUCTION_FORMAT21t register COMMA label_ref;
insn_format22b
: //e.g. add-int v0, v1, 123
INSTRUCTION_FORMAT22b REGISTER COMMA REGISTER COMMA integral_literal;
INSTRUCTION_FORMAT22b register COMMA register COMMA integral_literal;
insn_format22c_field
: //e.g. iput-object v1, v0 org/jf/HelloWorld2/HelloWorld2.helloWorld Ljava/lang/String;
INSTRUCTION_FORMAT22c_FIELD REGISTER COMMA REGISTER COMMA fully_qualified_field;
INSTRUCTION_FORMAT22c_FIELD register COMMA register COMMA fully_qualified_field;
insn_format22c_field_odex
: //e.g. iput-object-volatile v1, v0 org/jf/HelloWorld2/HelloWorld2.helloWorld Ljava/lang/String;
INSTRUCTION_FORMAT22c_FIELD_ODEX REGISTER COMMA REGISTER COMMA fully_qualified_field;
INSTRUCTION_FORMAT22c_FIELD_ODEX register COMMA register COMMA fully_qualified_field;
insn_format22c_type
: //e.g. instance-of v0, v1, Ljava/lang/String;
INSTRUCTION_FORMAT22c_TYPE REGISTER COMMA REGISTER COMMA nonvoid_type_descriptor;
INSTRUCTION_FORMAT22c_TYPE register COMMA register COMMA nonvoid_type_descriptor;
insn_format22cs_field
: //e.g. iget-quick v0, v1, field@0xc
INSTRUCTION_FORMAT22cs_FIELD REGISTER COMMA REGISTER COMMA FIELD_OFFSET;
INSTRUCTION_FORMAT22cs_FIELD register COMMA register COMMA FIELD_OFFSET;
insn_format22s
: //e.g. add-int/lit16 v0, v1, 12345
instruction_format22s REGISTER COMMA REGISTER COMMA integral_literal;
instruction_format22s register COMMA register COMMA integral_literal;
insn_format22t
: //e.g. if-eq v0, v1, endloop:
INSTRUCTION_FORMAT22t REGISTER COMMA REGISTER COMMA label_ref;
INSTRUCTION_FORMAT22t register COMMA register COMMA label_ref;
insn_format22x
: //e.g. move/from16 v1, v1234
INSTRUCTION_FORMAT22x REGISTER COMMA REGISTER;
INSTRUCTION_FORMAT22x register COMMA register;
insn_format23x
: //e.g. add-int v1, v2, v3
INSTRUCTION_FORMAT23x REGISTER COMMA REGISTER COMMA REGISTER;
INSTRUCTION_FORMAT23x register COMMA register COMMA register;
insn_format30t
: //e.g. goto/32 endloop:
@ -778,19 +783,19 @@ insn_format30t
insn_format31c
: //e.g. const-string/jumbo v1 "Hello World!"
INSTRUCTION_FORMAT31c REGISTER COMMA string_literal;
INSTRUCTION_FORMAT31c register COMMA string_literal;
insn_format31i
: //e.g. const v0, 123456
instruction_format31i REGISTER COMMA fixed_32bit_literal;
instruction_format31i register COMMA fixed_32bit_literal;
insn_format31t
: //e.g. fill-array-data v0, ArrayData:
INSTRUCTION_FORMAT31t REGISTER COMMA label_ref;
INSTRUCTION_FORMAT31t register COMMA label_ref;
insn_format32x
: //e.g. move/16 v4567, v1234
INSTRUCTION_FORMAT32x REGISTER COMMA REGISTER;
INSTRUCTION_FORMAT32x register COMMA register;
insn_format35c_method
: //e.g. invoke-virtual {v0,v1} java/io/PrintStream/print(Ljava/lang/Stream;)V
@ -834,7 +839,7 @@ insn_format3rms_method
insn_format51l
: //e.g. const-wide v0, 5000000000L
INSTRUCTION_FORMAT51l REGISTER COMMA fixed_literal;
INSTRUCTION_FORMAT51l register COMMA fixed_literal;
insn_array_data_directive
: ARRAY_DATA_DIRECTIVE

View File

@ -56,6 +56,8 @@ public class SmaliElementTypes {
new SmaliCompositeElementType("SOURCE_STATEMENT", SmaliSourceStatement.FACTORY);
public static final SmaliCompositeElementType REGISTERS_STATEMENT =
new SmaliCompositeElementType("REGISTERS_STATEMENT", SmaliRegistersStatement.FACTORY);
public static final SmaliCompositeElementType REGISTER_REFERENCE =
new SmaliCompositeElementType("REGISTER_REFERENCE", SmaliRegisterReference.FACTORY);
public static final SmaliCompositeElementType ACCESS_LIST =
new SmaliCompositeElementType("ACCESS_LIST", SmaliAccessList.FACTORY);
public static final SmaliCompositeElementType MEMBER_NAME =

View File

@ -84,4 +84,16 @@ public abstract class SmaliCompositeElement extends CompositePsiElement {
}
return null;
}
@SuppressWarnings("unchecked")
protected <T> T findAncestorByClass(Class<T> aClass) {
PsiElement parent = getParent();
while (parent != null) {
if (ReflectionCache.isInstance(parent, aClass)) {
return (T)parent;
}
parent = parent.getParent();
}
return null;
}
}

View File

@ -31,7 +31,11 @@
package org.jf.smalidea.psi.impl;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiAnnotationMemberValue;
import com.intellij.psi.tree.IElementType;
import org.jf.smali.LiteralTools;
import org.jf.smalidea.SmaliTokens;
import org.jf.smalidea.psi.SmaliCompositeElementFactory;
import org.jf.smalidea.psi.SmaliElementTypes;
@ -45,4 +49,27 @@ public class SmaliLiteral extends SmaliCompositeElement implements PsiAnnotation
public SmaliLiteral() {
super(SmaliElementTypes.LITERAL);
}
public long getIntegralValue() {
ASTNode literalNode = getNode().getFirstChildNode();
IElementType literalType = literalNode.getElementType();
if (literalType == SmaliTokens.LONG_LITERAL) {
return LiteralTools.parseLong(literalNode.getText());
} else if (literalType == SmaliTokens.NEGATIVE_INTEGER_LITERAL ||
literalType == SmaliTokens.POSITIVE_INTEGER_LITERAL) {
return LiteralTools.parseInt(literalNode.getText());
} else if (literalType == SmaliTokens.SHORT_LITERAL) {
return LiteralTools.parseShort(literalNode.getText());
} else if (literalType == SmaliTokens.CHAR_LITERAL) {
// TODO: implement this
return -1;
} else if (literalType == SmaliTokens.BYTE_LITERAL) {
return LiteralTools.parseByte(literalNode.getText());
} else if (literalType == SmaliTokens.BOOL_LITERAL) {
return Boolean.parseBoolean(literalNode.getText())?1:0;
} else {
throw new RuntimeException("Not an integral literal");
}
}
}

View File

@ -44,4 +44,17 @@ public class SmaliMethod extends SmaliStubBasedPsiElement<SmaliMethodStub> {
public SmaliMethod(@NotNull ASTNode node) {
super(node);
}
public int getRegisterCount() {
SmaliRegistersStatement registersStatement = findChildByClass(SmaliRegistersStatement.class);
if (registersStatement == null) {
return 0;
}
return registersStatement.getRegisterCount();
}
public int getParameterRegisterCount() {
// TODO: implement this
return 0;
}
}

View File

@ -0,0 +1,70 @@
/*
* Copyright 2014, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.smalidea.psi.impl;
import org.jetbrains.annotations.NotNull;
import org.jf.smalidea.psi.SmaliCompositeElementFactory;
import org.jf.smalidea.psi.SmaliElementTypes;
public class SmaliRegisterReference extends SmaliCompositeElement {
public static final SmaliCompositeElementFactory FACTORY = new SmaliCompositeElementFactory() {
@Override public SmaliCompositeElement createElement() {
return new SmaliRegisterReference();
}
};
public SmaliRegisterReference() {
super(SmaliElementTypes.REGISTER_REFERENCE);
}
@NotNull
public SmaliMethod getParentMethod() {
SmaliMethod parentMethod = findAncestorByClass(SmaliMethod.class);
assert parentMethod != null;
return parentMethod;
}
public int getRegisterNumber() {
int registerNumber = Integer.parseInt(getText().substring(1));
if (isParameterRegister()) {
SmaliMethod method = getParentMethod();
registerNumber += method.getRegisterCount() - method.getParameterRegisterCount();
}
return registerNumber;
}
public boolean isParameterRegister() {
return getText().charAt(0) == 'p';
}
}

View File

@ -31,6 +31,8 @@
package org.jf.smalidea.psi.impl;
import org.jetbrains.annotations.NotNull;
import org.jf.smalidea.SmaliTokens;
import org.jf.smalidea.psi.SmaliCompositeElementFactory;
import org.jf.smalidea.psi.SmaliElementTypes;
@ -44,4 +46,30 @@ public class SmaliRegistersStatement extends SmaliCompositeElement {
public SmaliRegistersStatement() {
super(SmaliElementTypes.REGISTERS_STATEMENT);
}
@NotNull
private SmaliMethod getParentMethod() {
return findAncestorByClass(SmaliMethod.class);
}
/**
* Get the total number of registers for the method
*/
public int getRegisterCount() {
SmaliLiteral literal = findChildByClass(SmaliLiteral.class);
assert literal != null;
long registerCount = literal.getIntegralValue();
// TODO: check for register count that's too large
if (isLocals()) {
SmaliMethod parentMethod = getParentMethod();
return (int)registerCount + parentMethod.getParameterRegisterCount();
}
return (int)registerCount;
}
private boolean isLocals() {
return findChildByType(SmaliTokens.LOCALS_DIRECTIVE) != null;
}
}

View File

@ -0,0 +1,78 @@
/*
* Copyright 2014, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.smalidea;
import com.intellij.psi.PsiElement;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
import junit.framework.Assert;
import org.jf.smalidea.psi.impl.SmaliFile;
import org.jf.smalidea.psi.impl.SmaliLiteral;
public class SmaliLiteralTest extends LightCodeInsightFixtureTestCase {
private void doTest(long expectedValue, String literalValue) {
String text =
".class public Lmy/pkg/blah; .super Ljava/lang/Object;\n" +
".method blah()V\n" +
" .registers <ref>" + literalValue + "\n" +
" return-void\n" +
".end method";
SmaliFile file = (SmaliFile)myFixture.addFileToProject("my/pkg/blah.smali",
text.replace("<ref>", ""));
PsiElement leafElement = file.findElementAt(text.indexOf("<ref>"));
Assert.assertNotNull(leafElement);
SmaliLiteral literalElement = (SmaliLiteral)leafElement.getParent();
Assert.assertNotNull(literalElement);
Assert.assertEquals(expectedValue, literalElement.getIntegralValue());
}
public void testIntegerValue() {
doTest(123, "123");
}
public void testLongValue() {
doTest(100, "100L");
}
public void testShortValue() {
doTest(99, "99s");
}
public void testByteValue() {
doTest(127, "127t");
}
// TODO: test char
// TODO: test bool
}

View File

@ -0,0 +1,61 @@
/*
* Copyright 2014, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.smalidea;
import com.intellij.psi.PsiElement;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
import junit.framework.Assert;
import org.jf.smalidea.psi.impl.SmaliFile;
import org.jf.smalidea.psi.impl.SmaliMethod;
public class SmaliMethodTest extends LightCodeInsightFixtureTestCase {
public void testMethodRegisters() {
String text =
".class public Lmy/pkg/blah; .super Ljava/lang/Object;\n" +
".me<ref>thod blah()V\n" +
" .registers 123\n" +
" return-void\n" +
".end method";
SmaliFile file = (SmaliFile)myFixture.addFileToProject("my/pkg/blah.smali",
text.replace("<ref>", ""));
PsiElement leafElement = file.findElementAt(text.indexOf("<ref>"));
Assert.assertNotNull(leafElement);
SmaliMethod methodElement = (SmaliMethod)leafElement.getParent();
Assert.assertNotNull(methodElement);
Assert.assertEquals(123, methodElement.getRegisterCount());
// TODO: test getParameterRegisterCount()
// TODO: test .locals directive
}
}

View File

@ -0,0 +1,61 @@
/*
* Copyright 2014, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.smalidea;
import com.intellij.psi.PsiElement;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
import junit.framework.Assert;
import org.jf.smalidea.psi.impl.SmaliFile;
import org.jf.smalidea.psi.impl.SmaliRegisterReference;
public class SmaliRegisterTest extends LightCodeInsightFixtureTestCase {
public void testRegisterReference() {
String text =
".class public Lmy/pkg/blah; .super Ljava/lang/Object;\n" +
".method blah()V\n" +
" .registers 123\n" +
" const <ref>v10, 123\n" +
" return-void\n" +
".end method";
SmaliFile file = (SmaliFile)myFixture.addFileToProject("my/pkg/blah.smali",
text.replace("<ref>", ""));
PsiElement leafElement = file.findElementAt(text.indexOf("<ref>"));
Assert.assertNotNull(leafElement);
SmaliRegisterReference registerReference = (SmaliRegisterReference)leafElement.getParent();
Assert.assertNotNull(registerReference);
Assert.assertEquals(10, registerReference.getRegisterNumber());
// TODO: test parameter register
}
}