diff options
author | Tor Norbye <tnorbye@google.com> | 2014-09-18 13:38:58 -0700 |
---|---|---|
committer | Tor Norbye <tnorbye@google.com> | 2014-09-18 13:38:58 -0700 |
commit | b5fb31ef6a38f19404859755dbd2e345215b97bf (patch) | |
tree | e8787c45e494dfcc558faf0f75956f8785c39b94 /plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationAttribute.java | |
parent | e222a9e1e66670a56e926a6b0f3e10231eeeb1fb (diff) | |
parent | e782c57d74000722f9db4c9426317410520670c6 (diff) | |
download | idea-b5fb31ef6a38f19404859755dbd2e345215b97bf.tar.gz |
Merge remote-tracking branch 'aosp/upstream-master' into merge
Conflicts:
.idea/libraries/asm_tools.xml
.idea/libraries/bouncy_castle.xml
.idea/libraries/builder_model.xml
.idea/libraries/commons_compress.xml
.idea/libraries/easymock_tools.xml
.idea/libraries/freemarker_2_3_20.xml
.idea/libraries/guava_tools.xml
.idea/libraries/kxml2.xml
.idea/libraries/lombok_ast.xml
.idea/libraries/mockito.xml
.idea/modules.xml
.idea/vcs.xml
build/scripts/layouts.gant
updater/src/com/intellij/updater/Runner.java
Change-Id: I8e1c173e00cd76c855b8a98543b0a0edfdd99d12
Diffstat (limited to 'plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationAttribute.java')
-rw-r--r-- | plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationAttribute.java | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationAttribute.java b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationAttribute.java new file mode 100644 index 000000000000..d04cb04166d5 --- /dev/null +++ b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationAttribute.java @@ -0,0 +1,184 @@ +/* + * Copyright 2000-2014 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.java.decompiler.struct.attr; + +import org.jetbrains.java.decompiler.code.CodeConstants; +import org.jetbrains.java.decompiler.modules.decompiler.exps.*; +import org.jetbrains.java.decompiler.struct.consts.ConstantPool; +import org.jetbrains.java.decompiler.struct.consts.PrimitiveConstant; +import org.jetbrains.java.decompiler.struct.gen.FieldDescriptor; +import org.jetbrains.java.decompiler.struct.gen.VarType; + +import java.io.DataInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class StructAnnotationAttribute extends StructGeneralAttribute { + + private List<AnnotationExprent> annotations; + + @Override + public void initContent(ConstantPool pool) throws IOException { + annotations = parseAnnotations(pool, stream()); + } + + public static List<AnnotationExprent> parseAnnotations(ConstantPool pool, DataInputStream data) throws IOException { + int len = data.readUnsignedShort(); + if (len > 0) { + List<AnnotationExprent> annotations = new ArrayList<AnnotationExprent>(len); + for (int i = 0; i < len; i++) { + annotations.add(parseAnnotation(data, pool)); + } + return annotations; + } + else { + return Collections.emptyList(); + } + } + + public static AnnotationExprent parseAnnotation(DataInputStream data, ConstantPool pool) throws IOException { + String className = pool.getPrimitiveConstant(data.readUnsignedShort()).getString(); + + List<String> names; + List<Exprent> values; + int len = data.readUnsignedShort(); + if (len > 0) { + names = new ArrayList<String>(len); + values = new ArrayList<Exprent>(len); + for (int i = 0; i < len; i++) { + names.add(pool.getPrimitiveConstant(data.readUnsignedShort()).getString()); + values.add(parseAnnotationElement(data, pool)); + } + } + else { + names = Collections.emptyList(); + values = Collections.emptyList(); + } + + return new AnnotationExprent(new VarType(className).value, names, values); + } + + public static Exprent parseAnnotationElement(DataInputStream data, ConstantPool pool) throws IOException { + int tag = data.readUnsignedByte(); + + switch (tag) { + case 'e': // enum constant + String className = pool.getPrimitiveConstant(data.readUnsignedShort()).getString(); + String constName = pool.getPrimitiveConstant(data.readUnsignedShort()).getString(); + FieldDescriptor descr = FieldDescriptor.parseDescriptor(className); + return new FieldExprent(constName, descr.type.value, true, null, descr); + + case 'c': // class + String descriptor = pool.getPrimitiveConstant(data.readUnsignedShort()).getString(); + VarType type = FieldDescriptor.parseDescriptor(descriptor).type; + + String value; + switch (type.type) { + case CodeConstants.TYPE_OBJECT: + value = type.value; + break; + case CodeConstants.TYPE_BYTE: + value = byte.class.getName(); + break; + case CodeConstants.TYPE_CHAR: + value = char.class.getName(); + break; + case CodeConstants.TYPE_DOUBLE: + value = double.class.getName(); + break; + case CodeConstants.TYPE_FLOAT: + value = float.class.getName(); + break; + case CodeConstants.TYPE_INT: + value = int.class.getName(); + break; + case CodeConstants.TYPE_LONG: + value = long.class.getName(); + break; + case CodeConstants.TYPE_SHORT: + value = short.class.getName(); + break; + case CodeConstants.TYPE_BOOLEAN: + value = boolean.class.getName(); + break; + case CodeConstants.TYPE_VOID: + value = void.class.getName(); + break; + default: + throw new RuntimeException("invalid class type: " + type.type); + } + return new ConstExprent(VarType.VARTYPE_CLASS, value); + + case '[': // array + List<Exprent> elements = Collections.emptyList(); + int len = data.readUnsignedShort(); + if (len > 0) { + elements = new ArrayList<Exprent>(len); + for (int i = 0; i < len; i++) { + elements.add(parseAnnotationElement(data, pool)); + } + } + + VarType newType; + if (elements.isEmpty()) { + newType = new VarType(CodeConstants.TYPE_OBJECT, 1, "java/lang/Object"); + } + else { + VarType elementType = elements.get(0).getExprType(); + newType = new VarType(elementType.type, 1, elementType.value); + } + + NewExprent newExpr = new NewExprent(newType, Collections.<Exprent>emptyList()); + newExpr.setDirectArrayInit(true); + newExpr.setLstArrayElements(elements); + return newExpr; + + case '@': // annotation + return parseAnnotation(data, pool); + + default: + PrimitiveConstant cn = pool.getPrimitiveConstant(data.readUnsignedShort()); + switch (tag) { + case 'B': + return new ConstExprent(VarType.VARTYPE_BYTE, cn.value); + case 'C': + return new ConstExprent(VarType.VARTYPE_CHAR, cn.value); + case 'D': + return new ConstExprent(VarType.VARTYPE_DOUBLE, cn.value); + case 'F': + return new ConstExprent(VarType.VARTYPE_FLOAT, cn.value); + case 'I': + return new ConstExprent(VarType.VARTYPE_INT, cn.value); + case 'J': + return new ConstExprent(VarType.VARTYPE_LONG, cn.value); + case 'S': + return new ConstExprent(VarType.VARTYPE_SHORT, cn.value); + case 'Z': + return new ConstExprent(VarType.VARTYPE_BOOLEAN, cn.value); + case 's': + return new ConstExprent(VarType.VARTYPE_STRING, cn.value); + default: + throw new RuntimeException("invalid element type!"); + } + } + } + + public List<AnnotationExprent> getAnnotations() { + return annotations; + } +} |