19a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee/** 29a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee * Copyright (C) 2006 Google Inc. 39a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee * 49a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee * Licensed under the Apache License, Version 2.0 (the "License"); 59a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee * you may not use this file except in compliance with the License. 69a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee * You may obtain a copy of the License at 79a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee * 89a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee * http://www.apache.org/licenses/LICENSE-2.0 99a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee * 109a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee * Unless required by applicable law or agreed to in writing, software 119a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee * distributed under the License is distributed on an "AS IS" BASIS, 129a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee * See the License for the specific language governing permissions and 149a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee * limitations under the License. 159a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee */ 169a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee 179a227bef3b82a045323ef2cf38ec60b2e42cf0felimpbizkit@gmail.compackage com.google.inject.internal.util; 189a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee 198743a0bb0fb49f30117c846880a7df2e7b36657eChristian Edward Gruberimport com.google.common.cache.CacheBuilder; 208743a0bb0fb49f30117c846880a7df2e7b36657eChristian Edward Gruberimport com.google.common.cache.CacheLoader; 218743a0bb0fb49f30117c846880a7df2e7b36657eChristian Edward Gruberimport com.google.common.cache.LoadingCache; 22b7a02b02d81c830d148355c90bc309bcd66fb592sberlinimport com.google.common.collect.MapMaker; 23b7a02b02d81c830d148355c90bc309bcd66fb592sberlin 249119a6353335397a8f5849899900e937dcdc05d3kevinbimport java.io.IOException; 259119a6353335397a8f5849899900e937dcdc05d3kevinbimport java.lang.reflect.Constructor; 269a3861be25ab810338456bcb4f606b6a0115fd95crazybobleeimport java.lang.reflect.Member; 279a3861be25ab810338456bcb4f606b6a0115fd95crazybobleeimport java.util.Map; 289a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee 299a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee/** 309a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee * Creates stack trace elements for members. 319a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee * 329a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee * @author crazybob@google.com (Bob Lee) 339a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee */ 349a3861be25ab810338456bcb4f606b6a0115fd95crazybobleepublic class StackTraceElements { 359a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee 36ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber private static final StackTraceElement[] EMPTY_STACK_TRACE = new StackTraceElement[0]; 37ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber private static final InMemoryStackTraceElement[] EMPTY_INMEMORY_STACK_TRACE = 38ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber new InMemoryStackTraceElement[0]; 39ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber 404f6274aa4a306efa727f9b37ad16ea3d331d22f0limpbizkit /*if[AOP]*/ 418743a0bb0fb49f30117c846880a7df2e7b36657eChristian Edward Gruber static final LoadingCache<Class<?>, LineNumbers> lineNumbersCache = 428743a0bb0fb49f30117c846880a7df2e7b36657eChristian Edward Gruber CacheBuilder.newBuilder().weakKeys().softValues().build( 438743a0bb0fb49f30117c846880a7df2e7b36657eChristian Edward Gruber new CacheLoader<Class<?>, LineNumbers>() { 448743a0bb0fb49f30117c846880a7df2e7b36657eChristian Edward Gruber public LineNumbers load(Class<?> key) { 458743a0bb0fb49f30117c846880a7df2e7b36657eChristian Edward Gruber try { 468743a0bb0fb49f30117c846880a7df2e7b36657eChristian Edward Gruber return new LineNumbers(key); 478743a0bb0fb49f30117c846880a7df2e7b36657eChristian Edward Gruber } 488743a0bb0fb49f30117c846880a7df2e7b36657eChristian Edward Gruber catch (IOException e) { 498743a0bb0fb49f30117c846880a7df2e7b36657eChristian Edward Gruber throw new RuntimeException(e); 508743a0bb0fb49f30117c846880a7df2e7b36657eChristian Edward Gruber } 518743a0bb0fb49f30117c846880a7df2e7b36657eChristian Edward Gruber } 528743a0bb0fb49f30117c846880a7df2e7b36657eChristian Edward Gruber }); 534f6274aa4a306efa727f9b37ad16ea3d331d22f0limpbizkit /*end[AOP]*/ 548743a0bb0fb49f30117c846880a7df2e7b36657eChristian Edward Gruber 55605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber private static Map<Object, Object> cache = new MapMaker().makeMap(); 56605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber private static final String UNKNOWN_SOURCE = "Unknown Source"; 578743a0bb0fb49f30117c846880a7df2e7b36657eChristian Edward Gruber 589a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee public static Object forMember(Member member) { 599a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee if (member == null) { 609532e6267f55105992301add5accfb5c62fdeed8limpbizkit return SourceProvider.UNKNOWN_SOURCE; 619a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee } 629a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee 639a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee Class declaringClass = member.getDeclaringClass(); 64564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit 654f6274aa4a306efa727f9b37ad16ea3d331d22f0limpbizkit /*if[AOP]*/ 668743a0bb0fb49f30117c846880a7df2e7b36657eChristian Edward Gruber LineNumbers lineNumbers = lineNumbersCache.getUnchecked(declaringClass); 674f6274aa4a306efa727f9b37ad16ea3d331d22f0limpbizkit String fileName = lineNumbers.getSource(); 684f6274aa4a306efa727f9b37ad16ea3d331d22f0limpbizkit Integer lineNumberOrNull = lineNumbers.getLineNumber(member); 694f6274aa4a306efa727f9b37ad16ea3d331d22f0limpbizkit int lineNumber = lineNumberOrNull == null ? lineNumbers.getFirstLine() : lineNumberOrNull; 704f6274aa4a306efa727f9b37ad16ea3d331d22f0limpbizkit /*end[AOP]*/ 714f6274aa4a306efa727f9b37ad16ea3d331d22f0limpbizkit /*if[NO_AOP] 724f6274aa4a306efa727f9b37ad16ea3d331d22f0limpbizkit String fileName = null; 734f6274aa4a306efa727f9b37ad16ea3d331d22f0limpbizkit int lineNumber = -1; 744f6274aa4a306efa727f9b37ad16ea3d331d22f0limpbizkit end[NO_AOP]*/ 75564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit 76dfee9fd5f78c5f1f769713b603e4e92a0b7b01e3sberlin Class<? extends Member> memberType = Classes.memberType(member); 77564053fc876faf8325bb0d11e009c650bfaa588blimpbizkit String memberName = memberType == Constructor.class ? "<init>" : member.getName(); 784f6274aa4a306efa727f9b37ad16ea3d331d22f0limpbizkit return new StackTraceElement(declaringClass.getName(), memberName, fileName, lineNumber); 799a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee } 809a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee 819a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee public static Object forType(Class<?> implementation) { 824f6274aa4a306efa727f9b37ad16ea3d331d22f0limpbizkit /*if[AOP]*/ 838743a0bb0fb49f30117c846880a7df2e7b36657eChristian Edward Gruber LineNumbers lineNumbers = lineNumbersCache.getUnchecked(implementation); 844f6274aa4a306efa727f9b37ad16ea3d331d22f0limpbizkit int lineNumber = lineNumbers.getFirstLine(); 854f6274aa4a306efa727f9b37ad16ea3d331d22f0limpbizkit String fileName = lineNumbers.getSource(); 864f6274aa4a306efa727f9b37ad16ea3d331d22f0limpbizkit /*end[AOP]*/ 874f6274aa4a306efa727f9b37ad16ea3d331d22f0limpbizkit /*if[NO_AOP] 884f6274aa4a306efa727f9b37ad16ea3d331d22f0limpbizkit String fileName = null; 894f6274aa4a306efa727f9b37ad16ea3d331d22f0limpbizkit int lineNumber = -1; 904f6274aa4a306efa727f9b37ad16ea3d331d22f0limpbizkit end[NO_AOP]*/ 914f6274aa4a306efa727f9b37ad16ea3d331d22f0limpbizkit 924f6274aa4a306efa727f9b37ad16ea3d331d22f0limpbizkit return new StackTraceElement(implementation.getName(), "class", fileName, lineNumber); 939a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee } 94605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber 95605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber /** 96605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber * Clears the internal cache for {@link StackTraceElement StackTraceElements}. 97605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber */ 98605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber public static void clearCache() { 99605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber cache.clear(); 100605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber } 101605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber 102605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber /** 103605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber * Returns encoded in-memory version of {@link StackTraceElement StackTraceElements}. 104605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber */ 105605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber public static InMemoryStackTraceElement[] convertToInMemoryStackTraceElement( 106605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber StackTraceElement[] stackTraceElements) { 107ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber if (stackTraceElements.length == 0) { 108ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber return EMPTY_INMEMORY_STACK_TRACE; 109ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber } 110605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber InMemoryStackTraceElement[] inMemoryStackTraceElements = 111605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber new InMemoryStackTraceElement[stackTraceElements.length]; 112605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber for (int i = 0; i < stackTraceElements.length; i++) { 113605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber inMemoryStackTraceElements[i] = 114605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber weakIntern(new InMemoryStackTraceElement(stackTraceElements[i])); 115605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber } 116605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber return inMemoryStackTraceElements; 117605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber } 118605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber 119605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber /** 120605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber * Decodes in-memory stack trace elements to regular {@link StackTraceElement StackTraceElements}. 121605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber */ 122605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber public static StackTraceElement[] convertToStackTraceElement( 123605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber InMemoryStackTraceElement[] inMemoryStackTraceElements) { 124ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber if (inMemoryStackTraceElements.length == 0) { 125ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber return EMPTY_STACK_TRACE; 126ba5acdf7cf1eef418cfdb463991ff76e7f3ded28Christian Edward Gruber } 127605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber StackTraceElement[] stackTraceElements = 128605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber new StackTraceElement[inMemoryStackTraceElements.length]; 129605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber for (int i = 0; i < inMemoryStackTraceElements.length; i++) { 130605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber String declaringClass = inMemoryStackTraceElements[i].getClassName(); 131605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber String methodName = inMemoryStackTraceElements[i].getMethodName(); 132605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber int lineNumber = inMemoryStackTraceElements[i].getLineNumber(); 133605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber stackTraceElements[i] = 134605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber new StackTraceElement(declaringClass, methodName, UNKNOWN_SOURCE, lineNumber); 135605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber } 136605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber return stackTraceElements; 137605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber } 138605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber 139605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber private static InMemoryStackTraceElement weakIntern( 140605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber InMemoryStackTraceElement inMemoryStackTraceElement) { 141605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber InMemoryStackTraceElement cached = 142605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber (InMemoryStackTraceElement) cache.get(inMemoryStackTraceElement); 143605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber if (cached != null) { 144605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber return cached; 145605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber } 146605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber inMemoryStackTraceElement = new InMemoryStackTraceElement( 147605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber weakIntern(inMemoryStackTraceElement.getClassName()), 148605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber weakIntern(inMemoryStackTraceElement.getMethodName()), 149605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber inMemoryStackTraceElement.getLineNumber()); 150605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber cache.put(inMemoryStackTraceElement, inMemoryStackTraceElement); 151605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber return inMemoryStackTraceElement; 152605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber } 153605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber 154605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber private static String weakIntern(String s) { 155605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber String cached = (String) cache.get(s); 156605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber if (cached != null) { 157605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber return cached; 158605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber } 159605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber cache.put(s, s); 160605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber return s; 161605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber } 162605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber 163605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber /** 164605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber * In-Memory version of {@link StackTraceElement} that does not store the file name. 165605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber */ 166605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber public static class InMemoryStackTraceElement { 167605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber private String declaringClass; 168605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber private String methodName; 169605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber private int lineNumber; 170605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber 171605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber InMemoryStackTraceElement(StackTraceElement ste) { 172605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber this(ste.getClassName(), ste.getMethodName(), ste.getLineNumber()); 173605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber } 174605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber 175605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber InMemoryStackTraceElement(String declaringClass, String methodName, int lineNumber) { 176605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber this.declaringClass = declaringClass; 177605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber this.methodName = methodName; 178605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber this.lineNumber = lineNumber; 179605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber } 180605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber 181605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber String getClassName() { 182605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber return declaringClass; 183605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber } 184605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber 185605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber String getMethodName() { 186605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber return methodName; 187605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber } 188605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber 189605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber int getLineNumber() { 190605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber return lineNumber; 191605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber } 192605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber 193605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber @Override 194605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber public boolean equals(Object obj) { 195605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber if (obj == this) { 196605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber return true; 197605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber } 198605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber if (!(obj instanceof InMemoryStackTraceElement)) { 199605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber return false; 200605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber } 201605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber InMemoryStackTraceElement e = (InMemoryStackTraceElement) obj; 202605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber return e.declaringClass.equals(declaringClass) && e.lineNumber == lineNumber && 203605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber methodName.equals(e.methodName); 204605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber } 205605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber 206605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber @Override 207605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber public int hashCode() { 208605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber int result = 31 * declaringClass.hashCode() + methodName.hashCode(); 209605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber result = 31 * result + lineNumber; 210605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber return result; 211605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber } 212605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber 213605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber @Override 214605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber public String toString() { 215605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber return declaringClass + "." + methodName + "(" + lineNumber + ")"; 216605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber } 217605bd086d3ecc4290ddfa4cf89fd840d22d1894cChristian Edward Gruber } 2189a3861be25ab810338456bcb4f606b6a0115fd95crazyboblee} 219