mirror of
https://github.com/revanced/smali.git
synced 2025-05-23 18:16:23 +02:00
Add support for renaming/moving classes
This commit is contained in:
parent
50810d1f5b
commit
07e6ade7fe
@ -19,6 +19,7 @@
|
||||
<syntaxHighlighter key="smali" implementationClass="org.jf.smalidea.SmaliHighlighter"/>
|
||||
<colorSettingsPage implementation="org.jf.smalidea.SmaliColorsPage"/>
|
||||
<lang.parserDefinition language="smali" implementationClass="org.jf.smalidea.SmaliParserDefinition"/>
|
||||
<lang.ast.factory language="smali" implementationClass="org.jf.smalidea.SmaliASTFactory"/>
|
||||
<java.elementFinder implementation="org.jf.smalidea.psi.index.SmaliClassFinder"/>
|
||||
<stubIndex implementation="org.jf.smalidea.psi.index.SmaliClassNameIndex"/>
|
||||
<debugger.positionManagerFactory implementation="org.jf.smalidea.debugging.SmaliPositionManagerFactory"/>
|
||||
|
19
smalidea/src/main/java/org/jf/smalidea/SmaliASTFactory.java
Normal file
19
smalidea/src/main/java/org/jf/smalidea/SmaliASTFactory.java
Normal file
@ -0,0 +1,19 @@
|
||||
package org.jf.smalidea;
|
||||
|
||||
import com.intellij.lang.ASTFactory;
|
||||
import com.intellij.psi.impl.source.tree.LeafElement;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jf.smalidea.psi.leaf.SmaliClassDescriptor;
|
||||
|
||||
public class SmaliASTFactory extends ASTFactory {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public LeafElement createLeaf(IElementType type, CharSequence text) {
|
||||
if (type == SmaliTokens.CLASS_DESCRIPTOR) {
|
||||
return new SmaliClassDescriptor(text);
|
||||
}
|
||||
return super.createLeaf(type, text);
|
||||
}
|
||||
}
|
@ -53,6 +53,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jf.smalidea.SmaliIcons;
|
||||
import org.jf.smalidea.psi.SmaliElementTypes;
|
||||
import org.jf.smalidea.psi.iface.SmaliModifierListOwner;
|
||||
import org.jf.smalidea.psi.leaf.SmaliClassDescriptor;
|
||||
import org.jf.smalidea.psi.stub.SmaliClassStub;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
@ -244,8 +245,16 @@ public class SmaliClass extends SmaliStubBasedPsiElement<SmaliClassStub> impleme
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable @Override public PsiIdentifier getNameIdentifier() {
|
||||
return null;
|
||||
@Nullable public SmaliClassStatement getClassStatement() {
|
||||
return getStubOrPsiChild(SmaliElementTypes.CLASS_STATEMENT);
|
||||
}
|
||||
|
||||
@Nullable @Override public SmaliClassDescriptor getNameIdentifier() {
|
||||
SmaliClassStatement classStatement = getClassStatement();
|
||||
if (classStatement == null) {
|
||||
return null;
|
||||
}
|
||||
return classStatement.getNameIdentifier();
|
||||
}
|
||||
|
||||
@Override public PsiElement getScope() {
|
||||
@ -269,7 +278,52 @@ public class SmaliClass extends SmaliStubBasedPsiElement<SmaliClassStub> impleme
|
||||
}
|
||||
|
||||
@Override public PsiElement setName(@NonNls @NotNull String name) throws IncorrectOperationException {
|
||||
return null;
|
||||
SmaliClassStatement classStatement = getClassStatement();
|
||||
if (classStatement == null) {
|
||||
throw new IncorrectOperationException();
|
||||
}
|
||||
|
||||
SmaliClassTypeElement classTypeElement = classStatement.getNameElement();
|
||||
if (classTypeElement == null) {
|
||||
throw new IncorrectOperationException();
|
||||
}
|
||||
|
||||
String expectedPath = "/" + getName() + ".smali";
|
||||
String actualPath = this.getContainingFile().getVirtualFile().getPath();
|
||||
if (actualPath.endsWith(expectedPath)) {
|
||||
getContainingFile().setName(name + ".smali");
|
||||
}
|
||||
|
||||
String packageName = this.getPackageName();
|
||||
String newName;
|
||||
if (packageName.length() > 0) {
|
||||
newName = packageName + "." + name;
|
||||
} else {
|
||||
newName = name;
|
||||
}
|
||||
classTypeElement.handleElementRename(newName);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setPackageName(@NonNls @NotNull String packageName) {
|
||||
SmaliClassStatement classStatement = getClassStatement();
|
||||
if (classStatement == null) {
|
||||
throw new IncorrectOperationException();
|
||||
}
|
||||
|
||||
SmaliClassTypeElement classTypeElement = classStatement.getNameElement();
|
||||
if (classTypeElement == null) {
|
||||
throw new IncorrectOperationException();
|
||||
}
|
||||
|
||||
String newName;
|
||||
if (packageName.length() > 0) {
|
||||
newName = packageName + "." + getName();
|
||||
} else {
|
||||
newName = getName();
|
||||
}
|
||||
|
||||
classTypeElement.handleElementRename(newName);
|
||||
}
|
||||
|
||||
@Nullable @Override public PsiDocComment getDocComment() {
|
||||
|
@ -35,6 +35,7 @@ import com.intellij.lang.ASTNode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jf.smalidea.psi.SmaliElementTypes;
|
||||
import org.jf.smalidea.psi.leaf.SmaliClassDescriptor;
|
||||
import org.jf.smalidea.psi.stub.SmaliClassStatementStub;
|
||||
|
||||
public class SmaliClassStatement extends SmaliStubBasedPsiElement<SmaliClassStatementStub> {
|
||||
@ -46,6 +47,20 @@ public class SmaliClassStatement extends SmaliStubBasedPsiElement<SmaliClassStat
|
||||
super(node);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public SmaliClassTypeElement getNameElement() {
|
||||
return findChildByClass(SmaliClassTypeElement.class);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public SmaliClassDescriptor getNameIdentifier() {
|
||||
SmaliClassTypeElement classTypeElement = getNameElement();
|
||||
if (classTypeElement == null) {
|
||||
return null;
|
||||
}
|
||||
return classTypeElement.getReferenceNameElement();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the fully qualified java-style name of the class in this .class statement
|
||||
*/
|
||||
|
@ -33,6 +33,7 @@ package org.jf.smalidea.psi.impl;
|
||||
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.codeStyle.CodeEditUtil;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
@ -40,6 +41,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jf.smalidea.psi.SmaliCompositeElementFactory;
|
||||
import org.jf.smalidea.psi.SmaliElementTypes;
|
||||
import org.jf.smalidea.psi.leaf.SmaliClassDescriptor;
|
||||
import org.jf.smalidea.util.NameUtils;
|
||||
|
||||
public class SmaliClassTypeElement extends SmaliTypeElement implements PsiJavaCodeReferenceElement {
|
||||
@ -102,12 +104,23 @@ public class SmaliClassTypeElement extends SmaliTypeElement implements PsiJavaCo
|
||||
}
|
||||
|
||||
@Override public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
|
||||
//TODO: implement this
|
||||
throw new IncorrectOperationException();
|
||||
SmaliClassDescriptor descriptor = getReferenceNameElement();
|
||||
if (descriptor == null) {
|
||||
throw new IncorrectOperationException();
|
||||
}
|
||||
|
||||
SmaliClassDescriptor newDescriptor = new SmaliClassDescriptor(NameUtils.javaToSmaliType(newElementName));
|
||||
CodeEditUtil.setNodeGenerated(newDescriptor, true);
|
||||
|
||||
this.replaceChild(descriptor, newDescriptor);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
|
||||
//TODO: implement this
|
||||
if (element instanceof PsiClass) {
|
||||
handleElementRename(((PsiClass) element).getQualifiedName());
|
||||
return this;
|
||||
}
|
||||
throw new IncorrectOperationException();
|
||||
}
|
||||
|
||||
@ -135,9 +148,8 @@ public class SmaliClassTypeElement extends SmaliTypeElement implements PsiJavaCo
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Nullable @Override public PsiElement getReferenceNameElement() {
|
||||
// TODO: implement if needed
|
||||
throw new UnsupportedOperationException();
|
||||
@Nullable @Override public SmaliClassDescriptor getReferenceNameElement() {
|
||||
return findChildByClass(SmaliClassDescriptor.class);
|
||||
}
|
||||
|
||||
@Nullable @Override public PsiReferenceParameterList getParameterList() {
|
||||
|
@ -85,6 +85,10 @@ public class SmaliFile extends PsiFileBase implements PsiClassOwner {
|
||||
}
|
||||
|
||||
@Override public void setPackageName(String packageName) throws IncorrectOperationException {
|
||||
// TODO: implement this
|
||||
SmaliClass smaliClass = getPsiClass();
|
||||
if (smaliClass == null) {
|
||||
return;
|
||||
}
|
||||
smaliClass.setPackageName(packageName);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,17 @@
|
||||
package org.jf.smalidea.psi.leaf;
|
||||
|
||||
import com.intellij.psi.PsiIdentifier;
|
||||
import com.intellij.psi.impl.source.tree.LeafPsiElement;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jf.smalidea.SmaliTokens;
|
||||
|
||||
public class SmaliClassDescriptor extends LeafPsiElement implements PsiIdentifier {
|
||||
public SmaliClassDescriptor(CharSequence text) {
|
||||
super(SmaliTokens.CLASS_DESCRIPTOR, text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IElementType getTokenType() {
|
||||
return SmaliTokens.CLASS_DESCRIPTOR;
|
||||
}
|
||||
}
|
68
smalidea/src/test/java/org/jf/smalidea/ClassMoveTest.java
Normal file
68
smalidea/src/test/java/org/jf/smalidea/ClassMoveTest.java
Normal file
@ -0,0 +1,68 @@
|
||||
package org.jf.smalidea;
|
||||
|
||||
import com.intellij.openapi.roots.JavaProjectRootsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.refactoring.MultiFileTestCase;
|
||||
import com.intellij.refactoring.PackageWrapper;
|
||||
import com.intellij.refactoring.move.moveClassesOrPackages.AutocreatingSingleSourceRootMoveDestination;
|
||||
import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesProcessor;
|
||||
import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ClassMoveTest extends MultiFileTestCase {
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return "testData";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected String getTestRoot() {
|
||||
return "/classMove/";
|
||||
}
|
||||
|
||||
public void testBasicFromNoPackage() {
|
||||
doTest("blah", "my");
|
||||
}
|
||||
|
||||
public void testBasicToNoPackage() {
|
||||
doTest("my.blah", "");
|
||||
}
|
||||
|
||||
private void doTest(@NotNull final String oldQualifiedName, @NotNull final String newPackage) {
|
||||
doTest(new PerformAction() {
|
||||
@Override
|
||||
public void performAction(VirtualFile rootDir, VirtualFile rootAfter) throws Exception {
|
||||
doMove(oldQualifiedName, newPackage);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void doMove(String oldQualifiedName, final String newPackage) throws Exception {
|
||||
final PsiClass testClass = myJavaFacade.findClass(oldQualifiedName, GlobalSearchScope.allScope(getProject()));
|
||||
|
||||
PsiDirectory newDirectory = MoveClassesOrPackagesUtil.chooseDestinationPackage(getProject(),
|
||||
newPackage, testClass.getContainingFile().getContainingDirectory());
|
||||
|
||||
final List<VirtualFile> contentSourceRoots =
|
||||
JavaProjectRootsUtil.getSuitableDestinationSourceRoots(getProject());
|
||||
|
||||
new MoveClassesOrPackagesProcessor(getProject(), new PsiClass[] {testClass},
|
||||
new AutocreatingSingleSourceRootMoveDestination(new PackageWrapper(getPsiManager(), newPackage),
|
||||
contentSourceRoots.get(0)), false, false, null).run();
|
||||
|
||||
/*new WriteCommandAction.Simple(getProject(), testClass.getContainingFile()) {
|
||||
@Override protected void run() throws Throwable {
|
||||
|
||||
|
||||
MoveClassesOrPackagesUtil.doMoveClass(testClass, newDirectory);
|
||||
}
|
||||
}.execute();*/
|
||||
}
|
||||
|
||||
}
|
51
smalidea/src/test/java/org/jf/smalidea/ClassRenameTest.java
Normal file
51
smalidea/src/test/java/org/jf/smalidea/ClassRenameTest.java
Normal file
@ -0,0 +1,51 @@
|
||||
package org.jf.smalidea;
|
||||
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.refactoring.MultiFileTestCase;
|
||||
import com.intellij.refactoring.rename.RenameProcessor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ClassRenameTest extends MultiFileTestCase {
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return "testData";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected String getTestRoot() {
|
||||
return "/classRename/";
|
||||
}
|
||||
|
||||
public void testBasicNoPackage() {
|
||||
doTest("blah", "blah2");
|
||||
}
|
||||
|
||||
public void testBasicWithPackage() {
|
||||
doTest("my.blah", "blah2");
|
||||
}
|
||||
|
||||
private void doTest(@NotNull final String oldQualifiedName, @NotNull final String newName) {
|
||||
doTest(new PerformAction() {
|
||||
@Override
|
||||
public void performAction(VirtualFile rootDir, VirtualFile rootAfter) throws Exception {
|
||||
doRename(oldQualifiedName, newName);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void doRename(String oldQualifiedName, String newName) throws Exception {
|
||||
PsiClass testClass = myJavaFacade.findClass(oldQualifiedName, GlobalSearchScope.allScope(getProject()));
|
||||
|
||||
RenameProcessor processor = new RenameProcessor(getProject(), testClass, newName, false, false);
|
||||
processor.run();
|
||||
|
||||
PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
|
||||
FileDocumentManager.getInstance().saveAllDocuments();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
.class public Lmy/blah;
|
||||
.super Lmy/blah;
|
||||
.implements Lmy/blah;
|
||||
|
||||
.annotation build Lmy/blah;
|
||||
value = .subannotation Lmy/blah;
|
||||
value = Lmy/blah;
|
||||
.end subannotation
|
||||
.end annotation
|
||||
|
||||
.field static public blah:Lmy/blah; = Lmy/blah;
|
||||
|
||||
.method public blah(Lmy/blah;)Lmy/blah;
|
||||
.registers 2
|
||||
.local p0, "this":Lmy/blah;
|
||||
|
||||
:start
|
||||
iget-object v0, v0, Lmy/blah;->blah:Lmy/blah;
|
||||
|
||||
invoke-virtual {v0}, Lmy/blah;->blah(Lmy/blah;)Lmy/blah;
|
||||
|
||||
instance-of v0, v0, Lmy/blah;
|
||||
check-cast v0, Lmy/blah;
|
||||
new-instance v0, Lmy/blah;
|
||||
const-class v0, Lmy/blah;
|
||||
throw-verification-error generic-error, Lmy/blah;
|
||||
|
||||
filled-new-array {v0, v0, v0, v0, v0}, Lmy/blah;
|
||||
new-array v0, v0, Lmy/blah;
|
||||
filled-new-array/range {v0}, Lmy/blah;
|
||||
:end
|
||||
|
||||
.catch Lmy/blah; { :start .. :end } :handler
|
||||
:handler
|
||||
return-void
|
||||
.end method
|
@ -0,0 +1,36 @@
|
||||
.class public Lblah;
|
||||
.super Lblah;
|
||||
.implements Lblah;
|
||||
|
||||
.annotation build Lblah;
|
||||
value = .subannotation Lblah;
|
||||
value = Lblah;
|
||||
.end subannotation
|
||||
.end annotation
|
||||
|
||||
.field static public blah:Lblah; = Lblah;
|
||||
|
||||
.method public blah(Lblah;)Lblah;
|
||||
.registers 2
|
||||
.local p0, "this":Lblah;
|
||||
|
||||
:start
|
||||
iget-object v0, v0, Lblah;->blah:Lblah;
|
||||
|
||||
invoke-virtual {v0}, Lblah;->blah(Lblah;)Lblah;
|
||||
|
||||
instance-of v0, v0, Lblah;
|
||||
check-cast v0, Lblah;
|
||||
new-instance v0, Lblah;
|
||||
const-class v0, Lblah;
|
||||
throw-verification-error generic-error, Lblah;
|
||||
|
||||
filled-new-array {v0, v0, v0, v0, v0}, Lblah;
|
||||
new-array v0, v0, Lblah;
|
||||
filled-new-array/range {v0}, Lblah;
|
||||
:end
|
||||
|
||||
.catch Lblah; { :start .. :end } :handler
|
||||
:handler
|
||||
return-void
|
||||
.end method
|
@ -0,0 +1,36 @@
|
||||
.class public Lblah;
|
||||
.super Lblah;
|
||||
.implements Lblah;
|
||||
|
||||
.annotation build Lblah;
|
||||
value = .subannotation Lblah;
|
||||
value = Lblah;
|
||||
.end subannotation
|
||||
.end annotation
|
||||
|
||||
.field static public blah:Lblah; = Lblah;
|
||||
|
||||
.method public blah(Lblah;)Lblah;
|
||||
.registers 2
|
||||
.local p0, "this":Lblah;
|
||||
|
||||
:start
|
||||
iget-object v0, v0, Lblah;->blah:Lblah;
|
||||
|
||||
invoke-virtual {v0}, Lblah;->blah(Lblah;)Lblah;
|
||||
|
||||
instance-of v0, v0, Lblah;
|
||||
check-cast v0, Lblah;
|
||||
new-instance v0, Lblah;
|
||||
const-class v0, Lblah;
|
||||
throw-verification-error generic-error, Lblah;
|
||||
|
||||
filled-new-array {v0, v0, v0, v0, v0}, Lblah;
|
||||
new-array v0, v0, Lblah;
|
||||
filled-new-array/range {v0}, Lblah;
|
||||
:end
|
||||
|
||||
.catch Lblah; { :start .. :end } :handler
|
||||
:handler
|
||||
return-void
|
||||
.end method
|
@ -0,0 +1,36 @@
|
||||
.class public Lmy/blah;
|
||||
.super Lmy/blah;
|
||||
.implements Lmy/blah;
|
||||
|
||||
.annotation build Lmy/blah;
|
||||
value = .subannotation Lmy/blah;
|
||||
value = Lmy/blah;
|
||||
.end subannotation
|
||||
.end annotation
|
||||
|
||||
.field static public blah:Lmy/blah; = Lmy/blah;
|
||||
|
||||
.method public blah(Lmy/blah;)Lmy/blah;
|
||||
.registers 2
|
||||
.local p0, "this":Lmy/blah;
|
||||
|
||||
:start
|
||||
iget-object v0, v0, Lmy/blah;->blah:Lmy/blah;
|
||||
|
||||
invoke-virtual {v0}, Lmy/blah;->blah(Lmy/blah;)Lmy/blah;
|
||||
|
||||
instance-of v0, v0, Lmy/blah;
|
||||
check-cast v0, Lmy/blah;
|
||||
new-instance v0, Lmy/blah;
|
||||
const-class v0, Lmy/blah;
|
||||
throw-verification-error generic-error, Lmy/blah;
|
||||
|
||||
filled-new-array {v0, v0, v0, v0, v0}, Lmy/blah;
|
||||
new-array v0, v0, Lmy/blah;
|
||||
filled-new-array/range {v0}, Lmy/blah;
|
||||
:end
|
||||
|
||||
.catch Lmy/blah; { :start .. :end } :handler
|
||||
:handler
|
||||
return-void
|
||||
.end method
|
@ -0,0 +1,36 @@
|
||||
.class public Lblah2;
|
||||
.super Lblah2;
|
||||
.implements Lblah2;
|
||||
|
||||
.annotation build Lblah2;
|
||||
value = .subannotation Lblah2;
|
||||
value = Lblah2;
|
||||
.end subannotation
|
||||
.end annotation
|
||||
|
||||
.field static public blah:Lblah2; = Lblah2;
|
||||
|
||||
.method public blah(Lblah2;)Lblah2;
|
||||
.registers 2
|
||||
.local p0, "this":Lblah2;
|
||||
|
||||
:start
|
||||
iget-object v0, v0, Lblah2;->blah:Lblah2;
|
||||
|
||||
invoke-virtual {v0}, Lblah2;->blah(Lblah2;)Lblah2;
|
||||
|
||||
instance-of v0, v0, Lblah2;
|
||||
check-cast v0, Lblah2;
|
||||
new-instance v0, Lblah2;
|
||||
const-class v0, Lblah2;
|
||||
throw-verification-error generic-error, Lblah2;
|
||||
|
||||
filled-new-array {v0, v0, v0, v0, v0}, Lblah2;
|
||||
new-array v0, v0, Lblah2;
|
||||
filled-new-array/range {v0}, Lblah2;
|
||||
:end
|
||||
|
||||
.catch Lblah2; { :start .. :end } :handler
|
||||
:handler
|
||||
return-void
|
||||
.end method
|
@ -0,0 +1,36 @@
|
||||
.class public Lblah;
|
||||
.super Lblah;
|
||||
.implements Lblah;
|
||||
|
||||
.annotation build Lblah;
|
||||
value = .subannotation Lblah;
|
||||
value = Lblah;
|
||||
.end subannotation
|
||||
.end annotation
|
||||
|
||||
.field static public blah:Lblah; = Lblah;
|
||||
|
||||
.method public blah(Lblah;)Lblah;
|
||||
.registers 2
|
||||
.local p0, "this":Lblah;
|
||||
|
||||
:start
|
||||
iget-object v0, v0, Lblah;->blah:Lblah;
|
||||
|
||||
invoke-virtual {v0}, Lblah;->blah(Lblah;)Lblah;
|
||||
|
||||
instance-of v0, v0, Lblah;
|
||||
check-cast v0, Lblah;
|
||||
new-instance v0, Lblah;
|
||||
const-class v0, Lblah;
|
||||
throw-verification-error generic-error, Lblah;
|
||||
|
||||
filled-new-array {v0, v0, v0, v0, v0}, Lblah;
|
||||
new-array v0, v0, Lblah;
|
||||
filled-new-array/range {v0}, Lblah;
|
||||
:end
|
||||
|
||||
.catch Lblah; { :start .. :end } :handler
|
||||
:handler
|
||||
return-void
|
||||
.end method
|
@ -0,0 +1,36 @@
|
||||
.class public Lmy/blah2;
|
||||
.super Lmy/blah2;
|
||||
.implements Lmy/blah2;
|
||||
|
||||
.annotation build Lmy/blah2;
|
||||
value = .subannotation Lmy/blah2;
|
||||
value = Lmy/blah2;
|
||||
.end subannotation
|
||||
.end annotation
|
||||
|
||||
.field static public blah:Lmy/blah2; = Lmy/blah2;
|
||||
|
||||
.method public blah(Lmy/blah2;)Lmy/blah2;
|
||||
.registers 2
|
||||
.local p0, "this":Lmy/blah2;
|
||||
|
||||
:start
|
||||
iget-object v0, v0, Lmy/blah2;->blah:Lmy/blah2;
|
||||
|
||||
invoke-virtual {v0}, Lmy/blah2;->blah(Lmy/blah2;)Lmy/blah2;
|
||||
|
||||
instance-of v0, v0, Lmy/blah2;
|
||||
check-cast v0, Lmy/blah2;
|
||||
new-instance v0, Lmy/blah2;
|
||||
const-class v0, Lmy/blah2;
|
||||
throw-verification-error generic-error, Lmy/blah2;
|
||||
|
||||
filled-new-array {v0, v0, v0, v0, v0}, Lmy/blah2;
|
||||
new-array v0, v0, Lmy/blah2;
|
||||
filled-new-array/range {v0}, Lmy/blah2;
|
||||
:end
|
||||
|
||||
.catch Lmy/blah2; { :start .. :end } :handler
|
||||
:handler
|
||||
return-void
|
||||
.end method
|
@ -0,0 +1,36 @@
|
||||
.class public Lmy/blah;
|
||||
.super Lmy/blah;
|
||||
.implements Lmy/blah;
|
||||
|
||||
.annotation build Lmy/blah;
|
||||
value = .subannotation Lmy/blah;
|
||||
value = Lmy/blah;
|
||||
.end subannotation
|
||||
.end annotation
|
||||
|
||||
.field static public blah:Lmy/blah; = Lmy/blah;
|
||||
|
||||
.method public blah(Lmy/blah;)Lmy/blah;
|
||||
.registers 2
|
||||
.local p0, "this":Lmy/blah;
|
||||
|
||||
:start
|
||||
iget-object v0, v0, Lmy/blah;->blah:Lmy/blah;
|
||||
|
||||
invoke-virtual {v0}, Lmy/blah;->blah(Lmy/blah;)Lmy/blah;
|
||||
|
||||
instance-of v0, v0, Lmy/blah;
|
||||
check-cast v0, Lmy/blah;
|
||||
new-instance v0, Lmy/blah;
|
||||
const-class v0, Lmy/blah;
|
||||
throw-verification-error generic-error, Lmy/blah;
|
||||
|
||||
filled-new-array {v0, v0, v0, v0, v0}, Lmy/blah;
|
||||
new-array v0, v0, Lmy/blah;
|
||||
filled-new-array/range {v0}, Lmy/blah;
|
||||
:end
|
||||
|
||||
.catch Lmy/blah; { :start .. :end } :handler
|
||||
:handler
|
||||
return-void
|
||||
.end method
|
Loading…
x
Reference in New Issue
Block a user