14a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver/* 24a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver * Copyright 2014, Google Inc. 34a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver * All rights reserved. 44a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver * 54a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver * Redistribution and use in source and binary forms, with or without 64a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver * modification, are permitted provided that the following conditions are 74a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver * met: 84a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver * 94a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver * * Redistributions of source code must retain the above copyright 104a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver * notice, this list of conditions and the following disclaimer. 114a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver * * Redistributions in binary form must reproduce the above 124a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver * copyright notice, this list of conditions and the following disclaimer 134a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver * in the documentation and/or other materials provided with the 144a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver * distribution. 154a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver * * Neither the name of Google Inc. nor the names of its 164a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver * contributors may be used to endorse or promote products derived from 174a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver * this software without specific prior written permission. 184a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver * 194a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 204a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 214a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 224a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 234a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 244a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 254a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 264a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 274a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 284a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 294a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 304a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver */ 314a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver 324a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruverpackage org.jf.smalidea.psi.impl; 334a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver 34ec63d20bb8cce01d3a07819c1416fac994e77e46Ben Gruverimport com.google.common.base.Supplier; 35ec63d20bb8cce01d3a07819c1416fac994e77e46Ben Gruverimport com.google.common.base.Suppliers; 36ec63d20bb8cce01d3a07819c1416fac994e77e46Ben Gruverimport com.google.common.collect.Maps; 37a788ab1dc3543ca4470c45a57f80ba8538c50a9cBen Gruverimport com.intellij.debugger.SourcePosition; 384a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruverimport com.intellij.lang.ASTNode; 396513dc012449f94668f2e207642e7763df52b729Ben Gruverimport com.intellij.openapi.editor.Document; 4056d5befed49287e7d77872030e640c34fc887c4aBen Gruverimport com.intellij.psi.*; 4156d5befed49287e7d77872030e640c34fc887c4aBen Gruverimport com.intellij.psi.PsiModifier.ModifierConstant; 4256d5befed49287e7d77872030e640c34fc887c4aBen Gruverimport com.intellij.psi.impl.PsiImplUtil; 4356d5befed49287e7d77872030e640c34fc887c4aBen Gruverimport com.intellij.psi.impl.PsiSuperMethodImplUtil; 4456d5befed49287e7d77872030e640c34fc887c4aBen Gruverimport com.intellij.psi.javadoc.PsiDocComment; 4556d5befed49287e7d77872030e640c34fc887c4aBen Gruverimport com.intellij.psi.util.MethodSignature; 4656d5befed49287e7d77872030e640c34fc887c4aBen Gruverimport com.intellij.psi.util.MethodSignatureBackedByPsiMethod; 47ea04d22ffd6dfba6cb4309550e0cbe445e0fef89Ben Gruverimport com.intellij.psi.util.PsiTreeUtil; 4856d5befed49287e7d77872030e640c34fc887c4aBen Gruverimport com.intellij.util.IncorrectOperationException; 4956d5befed49287e7d77872030e640c34fc887c4aBen Gruverimport org.jetbrains.annotations.NonNls; 504a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruverimport org.jetbrains.annotations.NotNull; 5156d5befed49287e7d77872030e640c34fc887c4aBen Gruverimport org.jetbrains.annotations.Nullable; 527b387e06c546e0b9f7caf4434df943651db32cdeBen Gruverimport org.jf.dexlib2.analysis.AnalysisException; 53cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruverimport org.jf.dexlib2.analysis.ClassPath; 54cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruverimport org.jf.dexlib2.analysis.MethodAnalyzer; 55cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruverimport org.jf.smalidea.dexlib.SmalideaMethod; 56ff4c85c5e4e380607fe1f89dc72db7339f77db8cBen Gruverimport org.jf.smalidea.dexlib.analysis.SmalideaClassProvider; 574a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruverimport org.jf.smalidea.psi.SmaliElementTypes; 5856d5befed49287e7d77872030e640c34fc887c4aBen Gruverimport org.jf.smalidea.psi.iface.SmaliModifierListOwner; 594a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruverimport org.jf.smalidea.psi.stub.SmaliMethodStub; 604a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver 61cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruverimport java.io.IOException; 629b97cfdf4882d4e306e3f81709be4649031cd799Ben Gruverimport java.util.Arrays; 6356d5befed49287e7d77872030e640c34fc887c4aBen Gruverimport java.util.List; 64ec63d20bb8cce01d3a07819c1416fac994e77e46Ben Gruverimport java.util.Map; 6556d5befed49287e7d77872030e640c34fc887c4aBen Gruver 6656d5befed49287e7d77872030e640c34fc887c4aBen Gruverpublic class SmaliMethod extends SmaliStubBasedPsiElement<SmaliMethodStub> 6744a0c9091ff58228a57bcd5ae5c0eceb8d223f36Ben Gruver implements PsiMethod, SmaliModifierListOwner, PsiAnnotationMethod { 684a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver public SmaliMethod(@NotNull SmaliMethodStub stub) { 694a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver super(stub, SmaliElementTypes.METHOD); 704a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver } 714a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver 724a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver public SmaliMethod(@NotNull ASTNode node) { 734a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver super(node); 744a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver } 7512b3579577627fd709d60d016b455f7e309f48acBen Gruver 7656d5befed49287e7d77872030e640c34fc887c4aBen Gruver @NotNull @Override public String getName() { 7756d5befed49287e7d77872030e640c34fc887c4aBen Gruver SmaliMethodStub stub = getStub(); 780a5f278d5fc25b8e1d2d644e7eefa2702579dee3Ben Gruver String name = null; 7956d5befed49287e7d77872030e640c34fc887c4aBen Gruver if (stub != null) { 800a5f278d5fc25b8e1d2d644e7eefa2702579dee3Ben Gruver name = stub.getName(); 810a5f278d5fc25b8e1d2d644e7eefa2702579dee3Ben Gruver } else { 820a5f278d5fc25b8e1d2d644e7eefa2702579dee3Ben Gruver SmaliMemberName nameIdentifier = getNameIdentifier(); 830a5f278d5fc25b8e1d2d644e7eefa2702579dee3Ben Gruver if (nameIdentifier != null) { 840a5f278d5fc25b8e1d2d644e7eefa2702579dee3Ben Gruver name = nameIdentifier.getText(); 850a5f278d5fc25b8e1d2d644e7eefa2702579dee3Ben Gruver } 860a5f278d5fc25b8e1d2d644e7eefa2702579dee3Ben Gruver } 870a5f278d5fc25b8e1d2d644e7eefa2702579dee3Ben Gruver if (name == null || name.isEmpty()) { 880a5f278d5fc25b8e1d2d644e7eefa2702579dee3Ben Gruver name = "<unnamed>"; 8956d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 900a5f278d5fc25b8e1d2d644e7eefa2702579dee3Ben Gruver return name; 9156d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 9256d5befed49287e7d77872030e640c34fc887c4aBen Gruver 9356d5befed49287e7d77872030e640c34fc887c4aBen Gruver @Override public boolean hasTypeParameters() { 9456d5befed49287e7d77872030e640c34fc887c4aBen Gruver // TODO: (generics) implement this 9556d5befed49287e7d77872030e640c34fc887c4aBen Gruver return false; 9656d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 9756d5befed49287e7d77872030e640c34fc887c4aBen Gruver 9856d5befed49287e7d77872030e640c34fc887c4aBen Gruver @NotNull 9956d5befed49287e7d77872030e640c34fc887c4aBen Gruver public SmaliMethodPrototype getMethodPrototype() { 10056d5befed49287e7d77872030e640c34fc887c4aBen Gruver return getRequiredStubOrPsiChild(SmaliElementTypes.METHOD_PROTOTYPE); 10156d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 10256d5befed49287e7d77872030e640c34fc887c4aBen Gruver 1030a5f278d5fc25b8e1d2d644e7eefa2702579dee3Ben Gruver @Nullable @Override public PsiType getReturnType() { 1047f6afa6a259cfcc06ce962029401189d080663a0Ben Gruver if (isConstructor()) return null; 1057f6afa6a259cfcc06ce962029401189d080663a0Ben Gruver return getMethodPrototype().getReturnType(); 10656d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 10756d5befed49287e7d77872030e640c34fc887c4aBen Gruver 1080a5f278d5fc25b8e1d2d644e7eefa2702579dee3Ben Gruver @Nullable @Override public PsiTypeElement getReturnTypeElement() { 1097f6afa6a259cfcc06ce962029401189d080663a0Ben Gruver if (isConstructor()) return null; 1107f6afa6a259cfcc06ce962029401189d080663a0Ben Gruver return getMethodPrototype().getReturnTypeElement(); 11156d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 11256d5befed49287e7d77872030e640c34fc887c4aBen Gruver 11356d5befed49287e7d77872030e640c34fc887c4aBen Gruver @NotNull @Override public SmaliMethodParamList getParameterList() { 11456d5befed49287e7d77872030e640c34fc887c4aBen Gruver return getMethodPrototype().getParameterList(); 11556d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 11656d5befed49287e7d77872030e640c34fc887c4aBen Gruver 1176a520231e74c1045e43f4b34182562979fbfc988Ben Gruver @NotNull @Override public SmaliThrowsList getThrowsList() { 1186a520231e74c1045e43f4b34182562979fbfc988Ben Gruver return getRequiredStubOrPsiChild(SmaliElementTypes.THROWS_LIST); 11956d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 12056d5befed49287e7d77872030e640c34fc887c4aBen Gruver 12156d5befed49287e7d77872030e640c34fc887c4aBen Gruver @Nullable @Override public PsiCodeBlock getBody() { 12256d5befed49287e7d77872030e640c34fc887c4aBen Gruver // not applicable 12356d5befed49287e7d77872030e640c34fc887c4aBen Gruver return null; 12456d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 12556d5befed49287e7d77872030e640c34fc887c4aBen Gruver 126a788ab1dc3543ca4470c45a57f80ba8538c50a9cBen Gruver @NotNull public List<SmaliInstruction> getInstructions() { 127a788ab1dc3543ca4470c45a57f80ba8538c50a9cBen Gruver return findChildrenByType(SmaliElementTypes.INSTRUCTION); 128a788ab1dc3543ca4470c45a57f80ba8538c50a9cBen Gruver } 129a788ab1dc3543ca4470c45a57f80ba8538c50a9cBen Gruver 1309b97cfdf4882d4e306e3f81709be4649031cd799Ben Gruver @NotNull public List<SmaliCatchStatement> getCatchStatements() { 1319b97cfdf4882d4e306e3f81709be4649031cd799Ben Gruver return Arrays.asList(findChildrenByClass(SmaliCatchStatement.class)); 1329b97cfdf4882d4e306e3f81709be4649031cd799Ben Gruver } 1339b97cfdf4882d4e306e3f81709be4649031cd799Ben Gruver 134a788ab1dc3543ca4470c45a57f80ba8538c50a9cBen Gruver @Nullable public SourcePosition getSourcePositionForCodeOffset(int offset) { 135a788ab1dc3543ca4470c45a57f80ba8538c50a9cBen Gruver for (SmaliInstruction instruction: getInstructions()) { 136a788ab1dc3543ca4470c45a57f80ba8538c50a9cBen Gruver if (instruction.getOffset() >= offset) { 137a788ab1dc3543ca4470c45a57f80ba8538c50a9cBen Gruver return SourcePosition.createFromElement(instruction); 138a788ab1dc3543ca4470c45a57f80ba8538c50a9cBen Gruver } 139a788ab1dc3543ca4470c45a57f80ba8538c50a9cBen Gruver } 140a788ab1dc3543ca4470c45a57f80ba8538c50a9cBen Gruver return null; 141a788ab1dc3543ca4470c45a57f80ba8538c50a9cBen Gruver } 142a788ab1dc3543ca4470c45a57f80ba8538c50a9cBen Gruver 1436513dc012449f94668f2e207642e7763df52b729Ben Gruver public int getOffsetForLine(int line) { 1446513dc012449f94668f2e207642e7763df52b729Ben Gruver PsiDocumentManager documentManager = PsiDocumentManager.getInstance(getProject()); 1456513dc012449f94668f2e207642e7763df52b729Ben Gruver final Document document = documentManager.getDocument(getContainingFile()); 1466513dc012449f94668f2e207642e7763df52b729Ben Gruver if (document == null) { 1476513dc012449f94668f2e207642e7763df52b729Ben Gruver return -1; 1486513dc012449f94668f2e207642e7763df52b729Ben Gruver } 1496513dc012449f94668f2e207642e7763df52b729Ben Gruver 1506513dc012449f94668f2e207642e7763df52b729Ben Gruver for (final SmaliInstruction instruction: getInstructions()) { 1516513dc012449f94668f2e207642e7763df52b729Ben Gruver int curLine = document.getLineNumber(instruction.getTextOffset()); 1526513dc012449f94668f2e207642e7763df52b729Ben Gruver if (curLine >= line) { 1536513dc012449f94668f2e207642e7763df52b729Ben Gruver return instruction.getOffset(); 1546513dc012449f94668f2e207642e7763df52b729Ben Gruver } 1556513dc012449f94668f2e207642e7763df52b729Ben Gruver } 1566513dc012449f94668f2e207642e7763df52b729Ben Gruver return -1; 1576513dc012449f94668f2e207642e7763df52b729Ben Gruver } 1586513dc012449f94668f2e207642e7763df52b729Ben Gruver 15912b3579577627fd709d60d016b455f7e309f48acBen Gruver public int getRegisterCount() { 16012b3579577627fd709d60d016b455f7e309f48acBen Gruver SmaliRegistersStatement registersStatement = findChildByClass(SmaliRegistersStatement.class); 16112b3579577627fd709d60d016b455f7e309f48acBen Gruver if (registersStatement == null) { 16212b3579577627fd709d60d016b455f7e309f48acBen Gruver return 0; 16312b3579577627fd709d60d016b455f7e309f48acBen Gruver } 16412b3579577627fd709d60d016b455f7e309f48acBen Gruver return registersStatement.getRegisterCount(); 16512b3579577627fd709d60d016b455f7e309f48acBen Gruver } 16612b3579577627fd709d60d016b455f7e309f48acBen Gruver 16712b3579577627fd709d60d016b455f7e309f48acBen Gruver public int getParameterRegisterCount() { 16856d5befed49287e7d77872030e640c34fc887c4aBen Gruver int parameterRegisterCount = getMethodPrototype().getParameterList().getParameterRegisterCount(); 16916dde79e587da4ea840293e196a02101b1aafc22Ben Gruver if (!isStatic()) { 17056d5befed49287e7d77872030e640c34fc887c4aBen Gruver parameterRegisterCount++; 17156d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 17256d5befed49287e7d77872030e640c34fc887c4aBen Gruver return parameterRegisterCount; 17356d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 17456d5befed49287e7d77872030e640c34fc887c4aBen Gruver 1759b97cfdf4882d4e306e3f81709be4649031cd799Ben Gruver @NotNull public SmaliParameterStatement[] getParameterStatements() { 17656d5befed49287e7d77872030e640c34fc887c4aBen Gruver return findChildrenByClass(SmaliParameterStatement.class); 17756d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 17856d5befed49287e7d77872030e640c34fc887c4aBen Gruver 17956d5befed49287e7d77872030e640c34fc887c4aBen Gruver @Override public boolean isConstructor() { 180ea04d22ffd6dfba6cb4309550e0cbe445e0fef89Ben Gruver // TODO: should this return true for the class initializer? 18156d5befed49287e7d77872030e640c34fc887c4aBen Gruver return hasModifierProperty("constructor") && !hasModifierProperty("static"); 18256d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 18356d5befed49287e7d77872030e640c34fc887c4aBen Gruver 18416dde79e587da4ea840293e196a02101b1aafc22Ben Gruver public boolean isStatic() { 18516dde79e587da4ea840293e196a02101b1aafc22Ben Gruver return hasModifierProperty("static"); 18616dde79e587da4ea840293e196a02101b1aafc22Ben Gruver } 18716dde79e587da4ea840293e196a02101b1aafc22Ben Gruver 18856d5befed49287e7d77872030e640c34fc887c4aBen Gruver @Override public boolean isVarArgs() { 18956d5befed49287e7d77872030e640c34fc887c4aBen Gruver return hasModifierProperty("varargs"); 19056d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 19156d5befed49287e7d77872030e640c34fc887c4aBen Gruver 19256d5befed49287e7d77872030e640c34fc887c4aBen Gruver @NotNull @Override public MethodSignature getSignature(@NotNull PsiSubstitutor substitutor) { 19356d5befed49287e7d77872030e640c34fc887c4aBen Gruver return MethodSignatureBackedByPsiMethod.create(this, substitutor); 19456d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 19556d5befed49287e7d77872030e640c34fc887c4aBen Gruver 1960a5f278d5fc25b8e1d2d644e7eefa2702579dee3Ben Gruver @Nullable @Override public SmaliMemberName getNameIdentifier() { 1970a5f278d5fc25b8e1d2d644e7eefa2702579dee3Ben Gruver return findChildByClass(SmaliMemberName.class); 19856d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 19956d5befed49287e7d77872030e640c34fc887c4aBen Gruver 20056d5befed49287e7d77872030e640c34fc887c4aBen Gruver @NotNull @Override public PsiMethod[] findSuperMethods() { 20156d5befed49287e7d77872030e640c34fc887c4aBen Gruver return PsiSuperMethodImplUtil.findSuperMethods(this); 20256d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 20356d5befed49287e7d77872030e640c34fc887c4aBen Gruver 20456d5befed49287e7d77872030e640c34fc887c4aBen Gruver @NotNull @Override public PsiMethod[] findSuperMethods(boolean checkAccess) { 20556d5befed49287e7d77872030e640c34fc887c4aBen Gruver return PsiSuperMethodImplUtil.findSuperMethods(this, checkAccess); 20656d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 20756d5befed49287e7d77872030e640c34fc887c4aBen Gruver 20856d5befed49287e7d77872030e640c34fc887c4aBen Gruver @NotNull @Override public PsiMethod[] findSuperMethods(PsiClass parentClass) { 20956d5befed49287e7d77872030e640c34fc887c4aBen Gruver return PsiSuperMethodImplUtil.findSuperMethods(this, parentClass); 21056d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 21156d5befed49287e7d77872030e640c34fc887c4aBen Gruver 21256d5befed49287e7d77872030e640c34fc887c4aBen Gruver @NotNull @Override 21356d5befed49287e7d77872030e640c34fc887c4aBen Gruver public List<MethodSignatureBackedByPsiMethod> findSuperMethodSignaturesIncludingStatic(boolean checkAccess) { 21456d5befed49287e7d77872030e640c34fc887c4aBen Gruver return PsiSuperMethodImplUtil.findSuperMethodSignaturesIncludingStatic(this, checkAccess); 21556d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 21656d5befed49287e7d77872030e640c34fc887c4aBen Gruver 21756d5befed49287e7d77872030e640c34fc887c4aBen Gruver @Nullable @Override public PsiMethod findDeepestSuperMethod() { 21856d5befed49287e7d77872030e640c34fc887c4aBen Gruver return PsiSuperMethodImplUtil.findDeepestSuperMethod(this); 21956d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 22056d5befed49287e7d77872030e640c34fc887c4aBen Gruver 22156d5befed49287e7d77872030e640c34fc887c4aBen Gruver @NotNull @Override public PsiMethod[] findDeepestSuperMethods() { 22256d5befed49287e7d77872030e640c34fc887c4aBen Gruver return PsiSuperMethodImplUtil.findDeepestSuperMethods(this); 22356d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 22456d5befed49287e7d77872030e640c34fc887c4aBen Gruver 22556d5befed49287e7d77872030e640c34fc887c4aBen Gruver @NotNull @Override public SmaliModifierList getModifierList() { 22656d5befed49287e7d77872030e640c34fc887c4aBen Gruver return getRequiredStubOrPsiChild(SmaliElementTypes.MODIFIER_LIST); 22756d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 22856d5befed49287e7d77872030e640c34fc887c4aBen Gruver 22956d5befed49287e7d77872030e640c34fc887c4aBen Gruver @Override public PsiElement setName(@NonNls @NotNull String name) throws IncorrectOperationException { 23048aacd2c01c116b154ee85df98024f6c6e4cb55aBen Gruver SmaliMemberName smaliMemberName = getNameIdentifier(); 23148aacd2c01c116b154ee85df98024f6c6e4cb55aBen Gruver if (smaliMemberName == null) { 23248aacd2c01c116b154ee85df98024f6c6e4cb55aBen Gruver throw new IncorrectOperationException(); 23348aacd2c01c116b154ee85df98024f6c6e4cb55aBen Gruver } 23448aacd2c01c116b154ee85df98024f6c6e4cb55aBen Gruver smaliMemberName.setName(name); 23548aacd2c01c116b154ee85df98024f6c6e4cb55aBen Gruver return this; 23656d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 23756d5befed49287e7d77872030e640c34fc887c4aBen Gruver 23856d5befed49287e7d77872030e640c34fc887c4aBen Gruver @NotNull @Override public HierarchicalMethodSignature getHierarchicalMethodSignature() { 23956d5befed49287e7d77872030e640c34fc887c4aBen Gruver return PsiSuperMethodImplUtil.getHierarchicalMethodSignature(this); 24056d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 24156d5befed49287e7d77872030e640c34fc887c4aBen Gruver 24256d5befed49287e7d77872030e640c34fc887c4aBen Gruver @Nullable @Override public PsiDocComment getDocComment() { 24356d5befed49287e7d77872030e640c34fc887c4aBen Gruver // not applicable 24456d5befed49287e7d77872030e640c34fc887c4aBen Gruver return null; 24556d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 24656d5befed49287e7d77872030e640c34fc887c4aBen Gruver 24756d5befed49287e7d77872030e640c34fc887c4aBen Gruver @Override public boolean isDeprecated() { 24856d5befed49287e7d77872030e640c34fc887c4aBen Gruver return PsiImplUtil.isDeprecatedByAnnotation(this); 24956d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 25056d5befed49287e7d77872030e640c34fc887c4aBen Gruver 25156d5befed49287e7d77872030e640c34fc887c4aBen Gruver @Nullable @Override public PsiTypeParameterList getTypeParameterList() { 25256d5befed49287e7d77872030e640c34fc887c4aBen Gruver // TODO: (generics) implement this 25356d5befed49287e7d77872030e640c34fc887c4aBen Gruver return null; 25456d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 25556d5befed49287e7d77872030e640c34fc887c4aBen Gruver 25656d5befed49287e7d77872030e640c34fc887c4aBen Gruver @NotNull @Override public PsiTypeParameter[] getTypeParameters() { 25756d5befed49287e7d77872030e640c34fc887c4aBen Gruver // TODO: (generics) implement this 25856d5befed49287e7d77872030e640c34fc887c4aBen Gruver return new PsiTypeParameter[0]; 25956d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 26056d5befed49287e7d77872030e640c34fc887c4aBen Gruver 26144a0c9091ff58228a57bcd5ae5c0eceb8d223f36Ben Gruver @Nullable @Override public SmaliClass getContainingClass() { 2621390c6cff68803dd82e4939a8e0cdddc690a6502Ben Gruver PsiElement parent = getParentByStub(); 26348aacd2c01c116b154ee85df98024f6c6e4cb55aBen Gruver if (parent instanceof SmaliClass) { 26448aacd2c01c116b154ee85df98024f6c6e4cb55aBen Gruver return (SmaliClass) parent; 26548aacd2c01c116b154ee85df98024f6c6e4cb55aBen Gruver } 26648aacd2c01c116b154ee85df98024f6c6e4cb55aBen Gruver return null; 26756d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 26856d5befed49287e7d77872030e640c34fc887c4aBen Gruver 26956d5befed49287e7d77872030e640c34fc887c4aBen Gruver @Override public boolean hasModifierProperty(@ModifierConstant @NonNls @NotNull String name) { 27056d5befed49287e7d77872030e640c34fc887c4aBen Gruver return getModifierList().hasModifierProperty(name); 27156d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 27256d5befed49287e7d77872030e640c34fc887c4aBen Gruver 27356d5befed49287e7d77872030e640c34fc887c4aBen Gruver @NotNull @Override public SmaliAnnotation[] getAnnotations() { 27456d5befed49287e7d77872030e640c34fc887c4aBen Gruver return getStubOrPsiChildren(SmaliElementTypes.ANNOTATION, new SmaliAnnotation[0]); 27556d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 27656d5befed49287e7d77872030e640c34fc887c4aBen Gruver 27756d5befed49287e7d77872030e640c34fc887c4aBen Gruver @NotNull @Override public SmaliAnnotation[] getApplicableAnnotations() { 27856d5befed49287e7d77872030e640c34fc887c4aBen Gruver return getAnnotations(); 27956d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 28056d5befed49287e7d77872030e640c34fc887c4aBen Gruver 28156d5befed49287e7d77872030e640c34fc887c4aBen Gruver @Nullable @Override public SmaliAnnotation findAnnotation(@NotNull @NonNls String qualifiedName) { 28256d5befed49287e7d77872030e640c34fc887c4aBen Gruver for (SmaliAnnotation annotation: getAnnotations()) { 28356d5befed49287e7d77872030e640c34fc887c4aBen Gruver if (qualifiedName.equals(annotation.getQualifiedName())) { 28456d5befed49287e7d77872030e640c34fc887c4aBen Gruver return annotation; 28556d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 28656d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 28756d5befed49287e7d77872030e640c34fc887c4aBen Gruver return null; 28856d5befed49287e7d77872030e640c34fc887c4aBen Gruver } 28956d5befed49287e7d77872030e640c34fc887c4aBen Gruver 29056d5befed49287e7d77872030e640c34fc887c4aBen Gruver @NotNull @Override public SmaliAnnotation addAnnotation(@NotNull @NonNls String qualifiedName) { 29112b3579577627fd709d60d016b455f7e309f48acBen Gruver // TODO: implement this 29256d5befed49287e7d77872030e640c34fc887c4aBen Gruver return null; 29312b3579577627fd709d60d016b455f7e309f48acBen Gruver } 294ec63d20bb8cce01d3a07819c1416fac994e77e46Ben Gruver 295ec63d20bb8cce01d3a07819c1416fac994e77e46Ben Gruver private final Supplier<Map<String, SmaliLabel>> labelMap = Suppliers.memoize( 296ec63d20bb8cce01d3a07819c1416fac994e77e46Ben Gruver new Supplier<Map<String, SmaliLabel>>() { 297ec63d20bb8cce01d3a07819c1416fac994e77e46Ben Gruver @Override public Map<String, SmaliLabel> get() { 298ec63d20bb8cce01d3a07819c1416fac994e77e46Ben Gruver Map<String, SmaliLabel> labelMap = Maps.newHashMap(); 299ec63d20bb8cce01d3a07819c1416fac994e77e46Ben Gruver for (SmaliLabel label: findChildrenByClass(SmaliLabel.class)) { 300ec63d20bb8cce01d3a07819c1416fac994e77e46Ben Gruver if (!labelMap.containsKey(label.getText())) { 301ec63d20bb8cce01d3a07819c1416fac994e77e46Ben Gruver labelMap.put(label.getText(), label); 302ec63d20bb8cce01d3a07819c1416fac994e77e46Ben Gruver } 303ec63d20bb8cce01d3a07819c1416fac994e77e46Ben Gruver } 304ec63d20bb8cce01d3a07819c1416fac994e77e46Ben Gruver return labelMap; 305ec63d20bb8cce01d3a07819c1416fac994e77e46Ben Gruver } 306ec63d20bb8cce01d3a07819c1416fac994e77e46Ben Gruver }); 307ec63d20bb8cce01d3a07819c1416fac994e77e46Ben Gruver 308ec63d20bb8cce01d3a07819c1416fac994e77e46Ben Gruver @Nullable public SmaliLabel getLabel(String name) { 309ec63d20bb8cce01d3a07819c1416fac994e77e46Ben Gruver return labelMap.get().get(name); 310ec63d20bb8cce01d3a07819c1416fac994e77e46Ben Gruver } 311cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver 312cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver private MethodAnalyzer methodAnalyzer = null; 313cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver 314ea04d22ffd6dfba6cb4309550e0cbe445e0fef89Ben Gruver @Nullable 315cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver public MethodAnalyzer getMethodAnalyzer() { 316cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver if (methodAnalyzer == null) { 317ea04d22ffd6dfba6cb4309550e0cbe445e0fef89Ben Gruver if (!PsiTreeUtil.hasErrorElements(this)) { 318ea04d22ffd6dfba6cb4309550e0cbe445e0fef89Ben Gruver ClassPath classPath; 319ea04d22ffd6dfba6cb4309550e0cbe445e0fef89Ben Gruver try { 320ff4c85c5e4e380607fe1f89dc72db7339f77db8cBen Gruver classPath = new ClassPath( 321ff4c85c5e4e380607fe1f89dc72db7339f77db8cBen Gruver new SmalideaClassProvider(getProject(), getContainingFile().getVirtualFile())); 322ea04d22ffd6dfba6cb4309550e0cbe445e0fef89Ben Gruver } catch (IOException ex) { 323ea04d22ffd6dfba6cb4309550e0cbe445e0fef89Ben Gruver throw new RuntimeException(ex); 324ea04d22ffd6dfba6cb4309550e0cbe445e0fef89Ben Gruver } 325cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver 3267b387e06c546e0b9f7caf4434df943651db32cdeBen Gruver try { 3277b387e06c546e0b9f7caf4434df943651db32cdeBen Gruver methodAnalyzer = new MethodAnalyzer(classPath, new SmalideaMethod(SmaliMethod.this), null, false); 3287b387e06c546e0b9f7caf4434df943651db32cdeBen Gruver } catch (AnalysisException ex) { 3297b387e06c546e0b9f7caf4434df943651db32cdeBen Gruver methodAnalyzer = null; 3307b387e06c546e0b9f7caf4434df943651db32cdeBen Gruver } 331ea04d22ffd6dfba6cb4309550e0cbe445e0fef89Ben Gruver } 332cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver } 333cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver return methodAnalyzer; 334cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver } 335cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver 336cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver @Override public void subtreeChanged() { 337cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver super.subtreeChanged(); 338cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver methodAnalyzer = null; 339cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver } 34037d1612e2f272b12d7ee556e05bb92f0e1a940b8Ben Gruver 34137d1612e2f272b12d7ee556e05bb92f0e1a940b8Ben Gruver @Override public int getTextOffset() { 34237d1612e2f272b12d7ee556e05bb92f0e1a940b8Ben Gruver SmaliMemberName smaliMemberName = getNameIdentifier(); 34337d1612e2f272b12d7ee556e05bb92f0e1a940b8Ben Gruver if (smaliMemberName != null) { 34437d1612e2f272b12d7ee556e05bb92f0e1a940b8Ben Gruver return smaliMemberName.getTextOffset(); 34537d1612e2f272b12d7ee556e05bb92f0e1a940b8Ben Gruver } 34637d1612e2f272b12d7ee556e05bb92f0e1a940b8Ben Gruver return super.getTextOffset(); 34737d1612e2f272b12d7ee556e05bb92f0e1a940b8Ben Gruver } 34844a0c9091ff58228a57bcd5ae5c0eceb8d223f36Ben Gruver 34944a0c9091ff58228a57bcd5ae5c0eceb8d223f36Ben Gruver @Nullable @Override public PsiAnnotationMemberValue getDefaultValue() { 35044a0c9091ff58228a57bcd5ae5c0eceb8d223f36Ben Gruver SmaliClass containingClass = getContainingClass(); 35144a0c9091ff58228a57bcd5ae5c0eceb8d223f36Ben Gruver if (containingClass == null || !containingClass.isAnnotationType()) { 35244a0c9091ff58228a57bcd5ae5c0eceb8d223f36Ben Gruver return null; 35344a0c9091ff58228a57bcd5ae5c0eceb8d223f36Ben Gruver } 35444a0c9091ff58228a57bcd5ae5c0eceb8d223f36Ben Gruver 35544a0c9091ff58228a57bcd5ae5c0eceb8d223f36Ben Gruver for (SmaliAnnotation annotation: containingClass.getAnnotations()) { 35644a0c9091ff58228a57bcd5ae5c0eceb8d223f36Ben Gruver String annotationType = annotation.getQualifiedName(); 35744a0c9091ff58228a57bcd5ae5c0eceb8d223f36Ben Gruver if (annotationType == null) { 35844a0c9091ff58228a57bcd5ae5c0eceb8d223f36Ben Gruver continue; 35944a0c9091ff58228a57bcd5ae5c0eceb8d223f36Ben Gruver } 36044a0c9091ff58228a57bcd5ae5c0eceb8d223f36Ben Gruver if (annotationType.equals("dalvik.annotation.AnnotationDefault")) { 36144a0c9091ff58228a57bcd5ae5c0eceb8d223f36Ben Gruver PsiAnnotationMemberValue value = annotation.findAttributeValue("value"); 36244a0c9091ff58228a57bcd5ae5c0eceb8d223f36Ben Gruver if (!(value instanceof SmaliAnnotation)) { 36344a0c9091ff58228a57bcd5ae5c0eceb8d223f36Ben Gruver return null; 36444a0c9091ff58228a57bcd5ae5c0eceb8d223f36Ben Gruver } 36544a0c9091ff58228a57bcd5ae5c0eceb8d223f36Ben Gruver SmaliAnnotation valueSubAnnotation = (SmaliAnnotation)value; 36644a0c9091ff58228a57bcd5ae5c0eceb8d223f36Ben Gruver return valueSubAnnotation.findAttributeValue(getName()); 36744a0c9091ff58228a57bcd5ae5c0eceb8d223f36Ben Gruver } 36844a0c9091ff58228a57bcd5ae5c0eceb8d223f36Ben Gruver } 36944a0c9091ff58228a57bcd5ae5c0eceb8d223f36Ben Gruver return null; 37044a0c9091ff58228a57bcd5ae5c0eceb8d223f36Ben Gruver } 3714a75c556bb149d754864c4c0c3ae2a94f3736dd1Ben Gruver} 372