diff --git a/smalidea/src/main/antlr3/smalideaParser.g b/smalidea/src/main/antlr3/smalideaParser.g index d4f06808..7eec730b 100644 --- a/smalidea/src/main/antlr3/smalideaParser.g +++ b/smalidea/src/main/antlr3/smalideaParser.g @@ -306,6 +306,7 @@ method @init { Marker marker = mark(); mark().done(SmaliElementTypes.MODIFIER_LIST); + mark().done(SmaliElementTypes.THROWS_LIST); } : METHOD_DIRECTIVE access_list member_name method_prototype statements_and_directives end_method_directive @@ -318,7 +319,6 @@ method end_method_directive : END_METHOD_DIRECTIVE; - statements_and_directives : ( ( ordered_method_item diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/SmaliElementTypes.java b/smalidea/src/main/java/org/jf/smalidea/psi/SmaliElementTypes.java index a517a1e5..ef325aa1 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/SmaliElementTypes.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/SmaliElementTypes.java @@ -31,7 +31,6 @@ package org.jf.smalidea.psi; -import org.jf.smalidea.psi.impl.SmaliInstruction; import org.jf.smalidea.psi.impl.*; import org.jf.smalidea.psi.stub.element.*; @@ -47,6 +46,7 @@ public class SmaliElementTypes { public static final SmaliModifierListElementType MODIFIER_LIST = SmaliModifierListElementType.INSTANCE; public static final SmaliExtendsListElementType EXTENDS_LIST = SmaliExtendsListElementType.INSTANCE; public static final SmaliImplementsListElementType IMPLEMENTS_LIST = SmaliImplementsListElementType.INSTANCE; + public static final SmaliThrowsListElementType THROWS_LIST = SmaliThrowsListElementType.INSTANCE; public static final SmaliCompositeElementType LITERAL = new SmaliCompositeElementType("LITERAL", SmaliLiteral.FACTORY); diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliClassTypeElement.java b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliClassTypeElement.java index 12fc259a..28c8eb4b 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliClassTypeElement.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliClassTypeElement.java @@ -43,6 +43,8 @@ import org.jf.smalidea.psi.SmaliElementTypes; import org.jf.smalidea.util.NameUtils; public class SmaliClassTypeElement extends SmaliTypeElement implements PsiJavaCodeReferenceElement { + public static final SmaliClassTypeElement[] EMPTY_ARRAY = new SmaliClassTypeElement[0]; + public static final SmaliCompositeElementFactory FACTORY = new SmaliCompositeElementFactory() { @Override public SmaliCompositeElement createElement() { return new SmaliClassTypeElement(); diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliMethod.java b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliMethod.java index bdb58188..2aec4bbe 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliMethod.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliMethod.java @@ -122,9 +122,8 @@ public class SmaliMethod extends SmaliStubBasedPsiElement return getMethodPrototype().getParameterList(); } - @NotNull @Override public PsiReferenceList getThrowsList() { - // TODO: add a fake reference list for throws - return null; + @NotNull @Override public SmaliThrowsList getThrowsList() { + return getRequiredStubOrPsiChild(SmaliElementTypes.THROWS_LIST); } @Nullable @Override public PsiCodeBlock getBody() { diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliThrowsList.java b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliThrowsList.java new file mode 100644 index 00000000..9cff5c34 --- /dev/null +++ b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliThrowsList.java @@ -0,0 +1,56 @@ +/* + * Copyright 2015, 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 com.intellij.lang.ASTNode; +import com.intellij.psi.PsiReferenceList; +import org.jetbrains.annotations.NotNull; +import org.jf.smalidea.psi.SmaliElementTypes; +import org.jf.smalidea.psi.stub.SmaliThrowsListStub; + +public class SmaliThrowsList extends SmaliBaseReferenceList implements PsiReferenceList { + public SmaliThrowsList(@NotNull ASTNode node) { + super(node); + } + + public SmaliThrowsList(@NotNull SmaliThrowsListStub stub) { + super(stub, SmaliElementTypes.THROWS_LIST); + } + + @NotNull @Override public SmaliClassTypeElement[] getReferenceElements() { + return SmaliClassTypeElement.EMPTY_ARRAY; + } + + @Override public Role getRole() { + return null; + } +} diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/stub/SmaliThrowsListStub.java b/smalidea/src/main/java/org/jf/smalidea/psi/stub/SmaliThrowsListStub.java new file mode 100644 index 00000000..94d239ec --- /dev/null +++ b/smalidea/src/main/java/org/jf/smalidea/psi/stub/SmaliThrowsListStub.java @@ -0,0 +1,43 @@ +/* + * Copyright 2015, 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.stub; + +import com.intellij.psi.stubs.StubElement; +import org.jetbrains.annotations.NotNull; +import org.jf.smalidea.psi.SmaliElementTypes; +import org.jf.smalidea.psi.impl.SmaliThrowsList; + +public class SmaliThrowsListStub extends SmaliBaseReferenceListStub { + public SmaliThrowsListStub(@NotNull StubElement parent) { + super(parent, SmaliElementTypes.THROWS_LIST, new String[0]); + } +} diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/stub/element/SmaliThrowsListElementType.java b/smalidea/src/main/java/org/jf/smalidea/psi/stub/element/SmaliThrowsListElementType.java new file mode 100644 index 00000000..b53af341 --- /dev/null +++ b/smalidea/src/main/java/org/jf/smalidea/psi/stub/element/SmaliThrowsListElementType.java @@ -0,0 +1,67 @@ +/* + * Copyright 2015, 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.stub.element; + +import com.intellij.lang.ASTNode; +import com.intellij.psi.stubs.StubElement; +import org.jetbrains.annotations.NotNull; +import org.jf.smalidea.psi.impl.SmaliThrowsList; +import org.jf.smalidea.psi.stub.SmaliThrowsListStub; + +public class SmaliThrowsListElementType + extends SmaliBaseReferenceListElementType { + public static final SmaliThrowsListElementType INSTANCE = new SmaliThrowsListElementType(); + + private SmaliThrowsListElementType() { + super("THROWS_LIST"); + } + + @NotNull @Override public String getExternalId() { + return "smali.throws_list"; + } + + @Override public SmaliThrowsList createPsi(@NotNull SmaliThrowsListStub stub) { + return new SmaliThrowsList(stub); + } + + @Override public SmaliThrowsList createPsi(@NotNull ASTNode node) { + return new SmaliThrowsList(node); + } + + @Override protected SmaliThrowsListStub createStub(StubElement parentStub, String[] types) { + return new SmaliThrowsListStub(parentStub); + } + + @Override public SmaliThrowsListStub createStub(@NotNull SmaliThrowsList psi, StubElement parentStub) { + return new SmaliThrowsListStub(parentStub); + } +} diff --git a/smalidea/src/test/java/org/jf/smalidea/SmaliMethodTest.java b/smalidea/src/test/java/org/jf/smalidea/SmaliMethodTest.java index 8285fcd9..5526b439 100644 --- a/smalidea/src/test/java/org/jf/smalidea/SmaliMethodTest.java +++ b/smalidea/src/test/java/org/jf/smalidea/SmaliMethodTest.java @@ -274,4 +274,17 @@ public class SmaliMethodTest extends LightCodeInsightFixtureTestCase { checkSourcePosition(smaliMethod, 40, Opcode.MOVE_RESULT); checkSourcePosition(smaliMethod, 42, Opcode.GOTO); } + + public void testThrowsList() { + String text = instructionsTestClass; + + SmaliFile file = (SmaliFile)myFixture.addFileToProject("my/pkg/blah.smali", text); + SmaliClass smaliClass = file.getPsiClass(); + SmaliMethod smaliMethod = smaliClass.getMethods()[0]; + + SmaliThrowsList throwsList = smaliMethod.getThrowsList(); + Assert.assertNotNull(throwsList); + Assert.assertEquals(0, throwsList.getReferencedTypes().length); + Assert.assertEquals(0, throwsList.getReferenceElements().length); + } } diff --git a/smalidea/testData/InvalidMethod.txt b/smalidea/testData/InvalidMethod.txt index ef1296ad..4fcc8ee6 100644 --- a/smalidea/testData/InvalidMethod.txt +++ b/smalidea/testData/InvalidMethod.txt @@ -23,6 +23,8 @@ smali.FILE SmaliMethod(METHOD) SmaliModifierList(MODIFIER_LIST) + SmaliThrowsList(THROWS_LIST) + PsiElement(METHOD_DIRECTIVE)('.method') PsiWhiteSpace(' ') PsiElement(ACCESS_LIST) diff --git a/smalidea/testData/InvalidMethod2.txt b/smalidea/testData/InvalidMethod2.txt index 955e9b9a..6b26f870 100644 --- a/smalidea/testData/InvalidMethod2.txt +++ b/smalidea/testData/InvalidMethod2.txt @@ -23,6 +23,8 @@ smali.FILE SmaliMethod(METHOD) SmaliModifierList(MODIFIER_LIST) + SmaliThrowsList(THROWS_LIST) + PsiElement(METHOD_DIRECTIVE)('.method') PsiWhiteSpace(' ') PsiElement(ACCESS_LIST) @@ -40,6 +42,8 @@ smali.FILE SmaliMethod(METHOD) SmaliModifierList(MODIFIER_LIST) + SmaliThrowsList(THROWS_LIST) + PsiElement(METHOD_DIRECTIVE)('.method') PsiElement(ACCESS_LIST) diff --git a/smalidea/testData/ParamListInvalidParameter.txt b/smalidea/testData/ParamListInvalidParameter.txt index 35016aa0..fa13e615 100644 --- a/smalidea/testData/ParamListInvalidParameter.txt +++ b/smalidea/testData/ParamListInvalidParameter.txt @@ -23,6 +23,8 @@ smali.FILE SmaliMethod(METHOD) SmaliModifierList(MODIFIER_LIST) + SmaliThrowsList(THROWS_LIST) + PsiElement(METHOD_DIRECTIVE)('.method') PsiWhiteSpace(' ') PsiElement(ACCESS_LIST) diff --git a/smalidea/testData/SuperClassInvalidSyntax2.txt b/smalidea/testData/SuperClassInvalidSyntax2.txt index 18f42faa..0dd28773 100644 --- a/smalidea/testData/SuperClassInvalidSyntax2.txt +++ b/smalidea/testData/SuperClassInvalidSyntax2.txt @@ -22,6 +22,8 @@ smali.FILE SmaliMethod(METHOD) SmaliModifierList(MODIFIER_LIST) + SmaliThrowsList(THROWS_LIST) + PsiElement(METHOD_DIRECTIVE)('.method') PsiWhiteSpace(' ') PsiElement(ACCESS_LIST)