From 7041accfe9ac901e93df6353b1be790f55a363a3 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Thu, 20 Apr 2017 19:27:41 +0300 Subject: [PATCH] reduced memory usage - use HashMap for attributes --- .../java/decompiler/main/ClassWriter.java | 30 +++++++++---------- .../decompiler/main/ClassesProcessor.java | 6 ++-- .../decompiler/main/rels/LambdaProcessor.java | 4 +-- .../main/rels/NestedClassProcessor.java | 2 +- .../modules/decompiler/ExprProcessor.java | 2 +- .../modules/decompiler/IdeaNotNullHelper.java | 12 +++----- .../modules/decompiler/exps/ExitExprent.java | 4 +-- .../modules/decompiler/exps/VarExprent.java | 4 +-- .../java/decompiler/struct/StructMember.java | 25 +++++++++------- .../java/decompiler/struct/StructMethod.java | 9 +++--- 10 files changed, 50 insertions(+), 48 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java index 0986a22..6233efe 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java +++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java @@ -271,7 +271,7 @@ public class ClassWriter { private static void addTracer(StructClass cls, StructMethod method, BytecodeMappingTracer tracer) { StructLineNumberTableAttribute table = - (StructLineNumberTableAttribute)method.getAttributes().getWithKey(StructGeneralAttribute.ATTRIBUTE_LINE_NUMBER_TABLE); + (StructLineNumberTableAttribute)method.getAttribute(StructGeneralAttribute.ATTRIBUTE_LINE_NUMBER_TABLE); tracer.setLineNumberTable(table); String key = InterpreterUtil.makeUniqueKey(method.getName(), method.getDescriptor()); DecompilerContext.getBytecodeSourceMapper().addTracer(cls.qualifiedName, key, tracer); @@ -287,8 +287,8 @@ public class ClassWriter { StructClass cl = wrapper.getClassStruct(); int flags = node.type == ClassNode.CLASS_ROOT ? cl.getAccessFlags() : node.access; - boolean isDeprecated = cl.getAttributes().containsKey("Deprecated"); - boolean isSynthetic = (flags & CodeConstants.ACC_SYNTHETIC) != 0 || cl.getAttributes().containsKey("Synthetic"); + boolean isDeprecated = cl.hasAttribute("Deprecated"); + boolean isSynthetic = (flags & CodeConstants.ACC_SYNTHETIC) != 0 || cl.hasAttribute("Synthetic"); boolean isEnum = DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_ENUM) && (flags & CodeConstants.ACC_ENUM) != 0; boolean isInterface = (flags & CodeConstants.ACC_INTERFACE) != 0; boolean isAnnotation = (flags & CodeConstants.ACC_ANNOTATION) != 0; @@ -379,7 +379,7 @@ public class ClassWriter { private void fieldToJava(ClassWrapper wrapper, StructClass cl, StructField fd, TextBuffer buffer, int indent, BytecodeMappingTracer tracer) { int start = buffer.length(); boolean isInterface = cl.hasModifier(CodeConstants.ACC_INTERFACE); - boolean isDeprecated = fd.getAttributes().containsKey("Deprecated"); + boolean isDeprecated = fd.hasAttribute("Deprecated"); boolean isEnum = fd.hasModifier(CodeConstants.ACC_ENUM) && DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_ENUM); if (isDeprecated) { @@ -407,7 +407,7 @@ public class ClassWriter { GenericFieldDescriptor descriptor = null; if (DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_GENERIC_SIGNATURES)) { - StructGenericSignatureAttribute attr = (StructGenericSignatureAttribute)fd.getAttributes().getWithKey("Signature"); + StructGenericSignatureAttribute attr = (StructGenericSignatureAttribute)fd.getAttribute("Signature"); if (attr != null) { descriptor = GenericMain.parseFieldSignature(attr.getSignature()); } @@ -448,7 +448,7 @@ public class ClassWriter { } else if (fd.hasModifier(CodeConstants.ACC_FINAL) && fd.hasModifier(CodeConstants.ACC_STATIC)) { StructConstantValueAttribute attr = - (StructConstantValueAttribute)fd.getAttributes().getWithKey(StructGeneralAttribute.ATTRIBUTE_CONSTANT_VALUE); + (StructConstantValueAttribute)fd.getAttribute(StructGeneralAttribute.ATTRIBUTE_CONSTANT_VALUE); if (attr != null) { PrimitiveConstant constant = cl.getPool().getPrimitiveConstant(attr.getIndex()); buffer.append(" = "); @@ -587,7 +587,7 @@ public class ClassWriter { boolean isInterface = cl.hasModifier(CodeConstants.ACC_INTERFACE); boolean isAnnotation = cl.hasModifier(CodeConstants.ACC_ANNOTATION); boolean isEnum = cl.hasModifier(CodeConstants.ACC_ENUM) && DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_ENUM); - boolean isDeprecated = mt.getAttributes().containsKey("Deprecated"); + boolean isDeprecated = mt.hasAttribute("Deprecated"); boolean clinit = false, init = false, dinit = false; MethodDescriptor md = MethodDescriptor.parseDescriptor(mt.getDescriptor()); @@ -609,7 +609,7 @@ public class ClassWriter { appendRenameComment(buffer, oldName, MType.METHOD, indent); } - boolean isSynthetic = (flags & CodeConstants.ACC_SYNTHETIC) != 0 || mt.getAttributes().containsKey("Synthetic"); + boolean isSynthetic = (flags & CodeConstants.ACC_SYNTHETIC) != 0 || mt.hasAttribute("Synthetic"); boolean isBridge = (flags & CodeConstants.ACC_BRIDGE) != 0; if (isSynthetic) { appendComment(buffer, "synthetic method", indent); @@ -647,7 +647,7 @@ public class ClassWriter { GenericMethodDescriptor descriptor = null; if (DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_GENERIC_SIGNATURES)) { - StructGenericSignatureAttribute attr = (StructGenericSignatureAttribute)mt.getAttributes().getWithKey("Signature"); + StructGenericSignatureAttribute attr = (StructGenericSignatureAttribute)mt.getAttribute("Signature"); if (attr != null) { descriptor = GenericMain.parseMethodSignature(attr.getSignature()); if (descriptor != null) { @@ -771,7 +771,7 @@ public class ClassWriter { buffer.append(')'); - StructExceptionsAttribute attr = (StructExceptionsAttribute)mt.getAttributes().getWithKey("Exceptions"); + StructExceptionsAttribute attr = (StructExceptionsAttribute)mt.getAttribute("Exceptions"); if ((descriptor != null && !descriptor.exceptions.isEmpty()) || attr != null) { throwsExceptions = true; buffer.append(" throws "); @@ -796,7 +796,7 @@ public class ClassWriter { if ((flags & (CodeConstants.ACC_ABSTRACT | CodeConstants.ACC_NATIVE)) != 0) { // native or abstract method (explicit or interface) if (isAnnotation) { - StructAnnDefaultAttribute attr = (StructAnnDefaultAttribute)mt.getAttributes().getWithKey("AnnotationDefault"); + StructAnnDefaultAttribute attr = (StructAnnDefaultAttribute)mt.getAttribute("AnnotationDefault"); if (attr != null) { buffer.append(" default "); buffer.append(attr.getDefaultValue().toJava(0, BytecodeMappingTracer.DUMMY)); @@ -943,7 +943,7 @@ public class ClassWriter { Set filter = new HashSet<>(); for (String name : ANNOTATION_ATTRIBUTES) { - StructAnnotationAttribute attribute = (StructAnnotationAttribute)mb.getAttributes().getWithKey(name); + StructAnnotationAttribute attribute = (StructAnnotationAttribute)mb.getAttribute(name); if (attribute != null) { for (AnnotationExprent annotation : attribute.getAnnotations()) { String text = annotation.toJava(indent, BytecodeMappingTracer.DUMMY).toString(); @@ -960,7 +960,7 @@ public class ClassWriter { Set filter = new HashSet<>(); for (String name : PARAMETER_ANNOTATION_ATTRIBUTES) { - StructAnnotationParameterAttribute attribute = (StructAnnotationParameterAttribute)mt.getAttributes().getWithKey(name); + StructAnnotationParameterAttribute attribute = (StructAnnotationParameterAttribute)mt.getAttribute(name); if (attribute != null) { List> annotations = attribute.getParamAnnotations(); if (param < annotations.size()) { @@ -978,7 +978,7 @@ public class ClassWriter { private static void appendTypeAnnotations(TextBuffer buffer, int indent, StructMember mb, int targetType, int index, Set filter) { for (String name : TYPE_ANNOTATION_ATTRIBUTES) { - StructTypeAnnotationAttribute attribute = (StructTypeAnnotationAttribute)mb.getAttributes().getWithKey(name); + StructTypeAnnotationAttribute attribute = (StructTypeAnnotationAttribute)mb.getAttribute(name); if (attribute != null) { for (TypeAnnotation annotation : attribute.getAnnotations()) { if (annotation.isTopLevel() && annotation.getTargetType() == targetType && (index < 0 || annotation.getIndex() == index)) { @@ -1041,7 +1041,7 @@ public class ClassWriter { public static GenericClassDescriptor getGenericClassDescriptor(StructClass cl) { if (DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_GENERIC_SIGNATURES)) { - StructGenericSignatureAttribute attr = (StructGenericSignatureAttribute)cl.getAttributes().getWithKey("Signature"); + StructGenericSignatureAttribute attr = (StructGenericSignatureAttribute)cl.getAttribute("Signature"); if (attr != null) { return GenericMain.parseClassSignature(attr.getSignature()); } diff --git a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java index 4afeddf..a743f98 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -66,7 +66,7 @@ public class ClassesProcessor { for (StructClass cl : context.getClasses().values()) { if (cl.isOwn() && !mapRootClasses.containsKey(cl.qualifiedName)) { if (bDecompileInner) { - StructInnerClassesAttribute inner = (StructInnerClassesAttribute)cl.getAttributes().getWithKey("InnerClasses"); + StructInnerClassesAttribute inner = (StructInnerClassesAttribute)cl.getAttribute("InnerClasses"); if (inner != null) { for (StructInnerClassesAttribute.Entry entry : inner.getEntries()) { @@ -157,7 +157,7 @@ public class ClassesProcessor { if (setNestedClasses != null) { StructClass scl = superNode.classStruct; - StructInnerClassesAttribute inner = (StructInnerClassesAttribute)scl.getAttributes().getWithKey("InnerClasses"); + StructInnerClassesAttribute inner = (StructInnerClassesAttribute)scl.getAttribute("InnerClasses"); if (inner == null || inner.getEntries().isEmpty()) { DecompilerContext.getLogger().writeMessage(superClass + " does not contain inner classes!", IFernflowerLogger.Severity.WARN); diff --git a/src/org/jetbrains/java/decompiler/main/rels/LambdaProcessor.java b/src/org/jetbrains/java/decompiler/main/rels/LambdaProcessor.java index 0063a15..3b2e74d 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/LambdaProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/rels/LambdaProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -56,7 +56,7 @@ public class LambdaProcessor { } StructBootstrapMethodsAttribute bootstrap = - (StructBootstrapMethodsAttribute)cl.getAttributes().getWithKey(StructGeneralAttribute.ATTRIBUTE_BOOTSTRAP_METHODS); + (StructBootstrapMethodsAttribute)cl.getAttribute(StructGeneralAttribute.ATTRIBUTE_BOOTSTRAP_METHODS); if (bootstrap == null || bootstrap.getMethodsNumber() == 0) { return false; // no bootstrap constants in pool } diff --git a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java index 897b394..974c057 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java @@ -192,7 +192,7 @@ public class NestedClassProcessor { if (!setEnclosing.isEmpty()) { StructEnclosingMethodAttribute attr = - (StructEnclosingMethodAttribute)child.classStruct.getAttributes().getWithKey("EnclosingMethod"); + (StructEnclosingMethodAttribute)child.classStruct.getAttribute("EnclosingMethod"); if (attr != null && attr.getMethodName() != null && node.classStruct.qualifiedName.equals(attr.getClassName()) && diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java index 930b1ee..f6005ba 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java @@ -288,7 +288,7 @@ public class ExprProcessor implements CodeConstants { ConstantPool pool = cl.getPool(); StructBootstrapMethodsAttribute bootstrap = - (StructBootstrapMethodsAttribute)cl.getAttributes().getWithKey(StructGeneralAttribute.ATTRIBUTE_BOOTSTRAP_METHODS); + (StructBootstrapMethodsAttribute)cl.getAttribute(StructGeneralAttribute.ATTRIBUTE_BOOTSTRAP_METHODS); BasicBlock block = stat.getBlock(); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/IdeaNotNullHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/IdeaNotNullHelper.java index 40d94fd..d6f917d 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/IdeaNotNullHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/IdeaNotNullHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,6 @@ import org.jetbrains.java.decompiler.struct.attr.StructAnnotationAttribute; import org.jetbrains.java.decompiler.struct.attr.StructAnnotationParameterAttribute; import org.jetbrains.java.decompiler.struct.attr.StructGeneralAttribute; import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor; -import org.jetbrains.java.decompiler.util.VBStyleCollection; import java.util.List; @@ -85,11 +84,10 @@ public class IdeaNotNullHelper { boolean thisvar = !mt.hasModifier(CodeConstants.ACC_STATIC); MethodDescriptor md = MethodDescriptor.parseDescriptor(mt.getDescriptor()); - VBStyleCollection attributes = mt.getAttributes(); // parameter annotations - StructAnnotationParameterAttribute param_annotations = (StructAnnotationParameterAttribute)attributes - .getWithKey(StructGeneralAttribute.ATTRIBUTE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS); + StructAnnotationParameterAttribute param_annotations = + (StructAnnotationParameterAttribute)mt.getAttribute(StructGeneralAttribute.ATTRIBUTE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS); if (param_annotations != null) { List> param_annotations_lists = param_annotations.getParamAnnotations(); @@ -172,13 +170,11 @@ public class IdeaNotNullHelper { private static boolean findAndRemoveReturnCheck(Statement stat, StructMethod mt) { - VBStyleCollection attributes = mt.getAttributes(); - boolean is_notnull_check = false; // method annotation, refers to the return value StructAnnotationAttribute attr = - (StructAnnotationAttribute)attributes.getWithKey(StructGeneralAttribute.ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS); + (StructAnnotationAttribute)mt.getAttribute(StructGeneralAttribute.ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS); if (attr != null) { List annotations = attr.getAnnotations(); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExitExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExitExprent.java index abfc4ab..0f16b66 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExitExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExitExprent.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -96,7 +96,7 @@ public class ExitExprent extends Exprent { ClassNode node = ((ClassNode)DecompilerContext.getProperty(DecompilerContext.CURRENT_CLASS_NODE)); if (method != null && node != null) { - StructExceptionsAttribute attr = (StructExceptionsAttribute)method.methodStruct.getAttributes().getWithKey("Exceptions"); + StructExceptionsAttribute attr = (StructExceptionsAttribute)method.methodStruct.getAttribute("Exceptions"); if (attr != null) { String classname = null; diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java index 0cb7fd1..d31f809 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java @@ -155,8 +155,8 @@ public class VarExprent extends Exprent { if (originalIndex != null) { // first try from signature if (DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_GENERIC_SIGNATURES)) { - StructLocalVariableTypeTableAttribute attr = (StructLocalVariableTypeTableAttribute)method.methodStruct.getAttributes() - .getWithKey(StructGeneralAttribute.ATTRIBUTE_LOCAL_VARIABLE_TYPE_TABLE); + StructLocalVariableTypeTableAttribute attr = (StructLocalVariableTypeTableAttribute)method.methodStruct + .getAttribute(StructGeneralAttribute.ATTRIBUTE_LOCAL_VARIABLE_TYPE_TABLE); if (attr != null) { String signature = attr.getSignature(originalIndex, visibleOffset); if (signature != null) { diff --git a/src/org/jetbrains/java/decompiler/struct/StructMember.java b/src/org/jetbrains/java/decompiler/struct/StructMember.java index bfe2270..585fcb2 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructMember.java +++ b/src/org/jetbrains/java/decompiler/struct/StructMember.java @@ -21,22 +21,27 @@ import org.jetbrains.java.decompiler.struct.attr.StructLocalVariableTableAttribu import org.jetbrains.java.decompiler.struct.attr.StructLocalVariableTypeTableAttribute; import org.jetbrains.java.decompiler.struct.consts.ConstantPool; import org.jetbrains.java.decompiler.util.DataInputFullStream; -import org.jetbrains.java.decompiler.util.VBStyleCollection; import java.io.IOException; +import java.util.HashMap; +import java.util.Map; public class StructMember { protected int accessFlags; - protected VBStyleCollection attributes; + protected Map attributes; public int getAccessFlags() { return accessFlags; } - public VBStyleCollection getAttributes() { - return attributes; + public StructGeneralAttribute getAttribute(String name) { + return attributes.get(name); + } + + public boolean hasAttribute(String name) { + return attributes.containsKey(name); } public boolean hasModifier(int modifier) { @@ -44,13 +49,13 @@ public class StructMember { } public boolean isSynthetic() { - return hasModifier(CodeConstants.ACC_SYNTHETIC) || attributes.containsKey(StructGeneralAttribute.ATTRIBUTE_SYNTHETIC); + return hasModifier(CodeConstants.ACC_SYNTHETIC) || hasAttribute(StructGeneralAttribute.ATTRIBUTE_SYNTHETIC); } - protected VBStyleCollection readAttributes(DataInputFullStream in, ConstantPool pool) throws IOException { + protected Map readAttributes(DataInputFullStream in, ConstantPool pool) throws IOException { int length = in.readUnsignedShort(); - VBStyleCollection attributes = new VBStyleCollection<>(length); + Map attributes = new HashMap<>(length); for (int i = 0; i < length; i++) { int nameIndex = in.readUnsignedShort(); String name = pool.getPrimitiveConstant(nameIndex).getString(); @@ -60,16 +65,16 @@ public class StructMember { if (attribute != null) { if (StructGeneralAttribute.ATTRIBUTE_LOCAL_VARIABLE_TABLE.equals(name) && attributes.containsKey(name)) { // merge all variable tables - StructLocalVariableTableAttribute table = (StructLocalVariableTableAttribute)attributes.getWithKey(name); + StructLocalVariableTableAttribute table = (StructLocalVariableTableAttribute)attributes.get(name); table.add((StructLocalVariableTableAttribute)attribute); } else if (StructGeneralAttribute.ATTRIBUTE_LOCAL_VARIABLE_TYPE_TABLE.equals(name) && attributes.containsKey(name)) { // merge all variable tables - StructLocalVariableTypeTableAttribute table = (StructLocalVariableTypeTableAttribute)attributes.getWithKey(name); + StructLocalVariableTypeTableAttribute table = (StructLocalVariableTypeTableAttribute)attributes.get(name); table.add((StructLocalVariableTypeTableAttribute)attribute); } else { - attributes.addWithKey(attribute, attribute.getName()); + attributes.put(attribute.getName(), attribute); } } } diff --git a/src/org/jetbrains/java/decompiler/struct/StructMethod.java b/src/org/jetbrains/java/decompiler/struct/StructMethod.java index d398c5e..64ee869 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructMethod.java +++ b/src/org/jetbrains/java/decompiler/struct/StructMethod.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +25,7 @@ import org.jetbrains.java.decompiler.util.VBStyleCollection; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Map; import static org.jetbrains.java.decompiler.code.CodeConstants.*; @@ -53,7 +54,7 @@ public class StructMethod extends StructMember { private int codeFullLength = 0; private InstructionSequence seq; private boolean expanded = false; - private VBStyleCollection codeAttributes; + private Map codeAttributes; public StructMethod(DataInputFullStream in, StructClass clStruct) throws IOException { classStruct = clStruct; @@ -69,7 +70,7 @@ public class StructMethod extends StructMember { attributes = readAttributes(in, pool); if (codeAttributes != null) { - attributes.addAllWithKey(codeAttributes); + attributes.putAll(codeAttributes); codeAttributes = null; } } @@ -391,7 +392,7 @@ public class StructMethod extends StructMember { } public StructLocalVariableTableAttribute getLocalVariableAttr() { - return (StructLocalVariableTableAttribute)getAttributes().getWithKey(StructGeneralAttribute.ATTRIBUTE_LOCAL_VARIABLE_TABLE); + return (StructLocalVariableTableAttribute)getAttribute(StructGeneralAttribute.ATTRIBUTE_LOCAL_VARIABLE_TABLE); } @Override