java-decompiler: post-import cleanup (formatting and copyright)
This commit is contained in:
@@ -1,26 +1,20 @@
|
||||
/*
|
||||
* Fernflower - The Analytical Java Decompiler
|
||||
* http://www.reversed-java.com
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* (C) 2008 - 2010, Stiver
|
||||
* 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
|
||||
*
|
||||
* This software is NEITHER public domain NOR free software
|
||||
* as per GNU License. See license.txt for more details.
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* This software is distributed WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.
|
||||
* 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.consts;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jetbrains.java.decompiler.code.CodeConstants;
|
||||
import org.jetbrains.java.decompiler.main.DecompilerContext;
|
||||
import org.jetbrains.java.decompiler.modules.renamer.PoolInterceptor;
|
||||
@@ -28,289 +22,297 @@ import org.jetbrains.java.decompiler.struct.gen.FieldDescriptor;
|
||||
import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor;
|
||||
import org.jetbrains.java.decompiler.struct.gen.VarType;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ConstantPool {
|
||||
|
||||
public static final int FIELD = 1;
|
||||
|
||||
public static final int METHOD = 2;
|
||||
|
||||
// *****************************************************************************
|
||||
// private fields
|
||||
// *****************************************************************************
|
||||
|
||||
private List<PooledConstant> pool = new ArrayList<PooledConstant>();
|
||||
|
||||
private PoolInterceptor interceptor;
|
||||
public static final int FIELD = 1;
|
||||
|
||||
// *****************************************************************************
|
||||
// constructors
|
||||
// *****************************************************************************
|
||||
|
||||
public ConstantPool(DataInputStream in) throws IOException {
|
||||
|
||||
int size = in.readUnsignedShort();
|
||||
public static final int METHOD = 2;
|
||||
|
||||
int[] pass = new int[size];
|
||||
|
||||
// first dummy constant
|
||||
pool.add(null);
|
||||
|
||||
// first pass: read the elements
|
||||
for (int i = 1; i < size; i++) {
|
||||
// *****************************************************************************
|
||||
// private fields
|
||||
// *****************************************************************************
|
||||
|
||||
byte tag = (byte)in.readUnsignedByte();
|
||||
private List<PooledConstant> pool = new ArrayList<PooledConstant>();
|
||||
|
||||
switch (tag) {
|
||||
case CodeConstants.CONSTANT_Utf8:
|
||||
pool.add(new PrimitiveConstant(CodeConstants.CONSTANT_Utf8, in.readUTF()));
|
||||
break;
|
||||
case CodeConstants.CONSTANT_Integer:
|
||||
pool.add(new PrimitiveConstant(CodeConstants.CONSTANT_Integer, new Integer(in.readInt())));
|
||||
break;
|
||||
case CodeConstants.CONSTANT_Float:
|
||||
pool.add(new PrimitiveConstant(CodeConstants.CONSTANT_Float, new Float(in.readFloat())));
|
||||
break;
|
||||
case CodeConstants.CONSTANT_Long:
|
||||
pool.add(new PrimitiveConstant(CodeConstants.CONSTANT_Long, new Long(in.readLong())));
|
||||
pool.add(null);
|
||||
i++;
|
||||
break;
|
||||
case CodeConstants.CONSTANT_Double:
|
||||
pool.add(new PrimitiveConstant(CodeConstants.CONSTANT_Double, new Double(in.readDouble())));
|
||||
pool.add(null);
|
||||
i++;
|
||||
break;
|
||||
case CodeConstants.CONSTANT_Class:
|
||||
case CodeConstants.CONSTANT_String:
|
||||
case CodeConstants.CONSTANT_MethodType:
|
||||
pool.add(new PrimitiveConstant(tag, in.readUnsignedShort()));
|
||||
pass[i] = 1;
|
||||
break;
|
||||
case CodeConstants.CONSTANT_Fieldref:
|
||||
case CodeConstants.CONSTANT_Methodref:
|
||||
case CodeConstants.CONSTANT_InterfaceMethodref:
|
||||
case CodeConstants.CONSTANT_NameAndType:
|
||||
case CodeConstants.CONSTANT_InvokeDynamic:
|
||||
pool.add(new LinkConstant(tag, in.readUnsignedShort(), in.readUnsignedShort()));
|
||||
if(tag == CodeConstants.CONSTANT_NameAndType) {
|
||||
pass[i] = 1;
|
||||
} else {
|
||||
pass[i] = 2;
|
||||
}
|
||||
break;
|
||||
case CodeConstants.CONSTANT_MethodHandle:
|
||||
pool.add(new LinkConstant(tag, in.readUnsignedByte(), in.readUnsignedShort()));
|
||||
pass[i] = 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// resolving complex pool elements
|
||||
for(int pass_index = 1; pass_index <= 3; pass_index++) {
|
||||
for(int i = 1; i < size; i++) {
|
||||
if(pass[i] == pass_index) {
|
||||
pool.get(i).resolveConstant(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get global constant pool interceptor instance, if any available
|
||||
interceptor = DecompilerContext.getPoolInterceptor();
|
||||
}
|
||||
private PoolInterceptor interceptor;
|
||||
|
||||
// *****************************************************************************
|
||||
// public methods
|
||||
// *****************************************************************************
|
||||
|
||||
public void writeToOutputStream(DataOutputStream out) throws FileNotFoundException, IOException {
|
||||
|
||||
out.writeShort(pool.size());
|
||||
for(int i=1;i<pool.size();i++) {
|
||||
PooledConstant cnst = (PooledConstant)pool.get(i);
|
||||
if(cnst!=null) {
|
||||
cnst.writeToStream(out);
|
||||
}
|
||||
}
|
||||
}
|
||||
// *****************************************************************************
|
||||
// constructors
|
||||
// *****************************************************************************
|
||||
|
||||
public static void skipPool(DataInputStream in) throws IOException {
|
||||
|
||||
int size = in.readUnsignedShort();
|
||||
public ConstantPool(DataInputStream in) throws IOException {
|
||||
|
||||
for (int i = 1; i < size; i++) {
|
||||
switch (in.readUnsignedByte()) {
|
||||
case CodeConstants.CONSTANT_Utf8:
|
||||
in.readUTF();
|
||||
break;
|
||||
case CodeConstants.CONSTANT_Integer:
|
||||
case CodeConstants.CONSTANT_Float:
|
||||
case CodeConstants.CONSTANT_Fieldref:
|
||||
case CodeConstants.CONSTANT_Methodref:
|
||||
case CodeConstants.CONSTANT_InterfaceMethodref:
|
||||
case CodeConstants.CONSTANT_NameAndType:
|
||||
case CodeConstants.CONSTANT_InvokeDynamic:
|
||||
in.skip(4);
|
||||
break;
|
||||
case CodeConstants.CONSTANT_Long:
|
||||
case CodeConstants.CONSTANT_Double:
|
||||
in.skip(8);
|
||||
i++;
|
||||
break;
|
||||
case CodeConstants.CONSTANT_Class:
|
||||
case CodeConstants.CONSTANT_String:
|
||||
case CodeConstants.CONSTANT_MethodType:
|
||||
in.skip(2);
|
||||
break;
|
||||
case CodeConstants.CONSTANT_MethodHandle:
|
||||
in.skip(3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return pool.size();
|
||||
}
|
||||
|
||||
public String[] getClassElement(int element_type, int class_index, int name_index, int descriptor_index) {
|
||||
|
||||
String classname = ((PrimitiveConstant)getConstant(class_index)).getString();
|
||||
String elementname = ((PrimitiveConstant)getConstant(name_index)).getString();
|
||||
String descriptor = ((PrimitiveConstant)getConstant(descriptor_index)).getString();
|
||||
|
||||
if(interceptor != null) {
|
||||
String new_element = interceptor.getName(classname+" "+elementname+" "+descriptor);
|
||||
|
||||
if(new_element != null) {
|
||||
elementname = new_element.split(" ")[1];
|
||||
}
|
||||
|
||||
String new_descriptor = buildNewDescriptor(element_type == FIELD?CodeConstants.CONSTANT_Fieldref:CodeConstants.CONSTANT_Methodref,
|
||||
descriptor);
|
||||
if(new_descriptor != null) {
|
||||
descriptor = new_descriptor;
|
||||
}
|
||||
}
|
||||
int size = in.readUnsignedShort();
|
||||
|
||||
return new String[] {elementname, descriptor};
|
||||
}
|
||||
|
||||
public PooledConstant getConstant(int index) {
|
||||
return pool.get(index);
|
||||
}
|
||||
int[] pass = new int[size];
|
||||
|
||||
public PrimitiveConstant getPrimitiveConstant(int index) {
|
||||
PrimitiveConstant cn = (PrimitiveConstant)getConstant(index);
|
||||
|
||||
if(cn != null && interceptor != null) {
|
||||
if(cn.type == CodeConstants.CONSTANT_Class) {
|
||||
String newname = buildNewClassname(cn.getString());
|
||||
if(newname != null) {
|
||||
cn = new PrimitiveConstant(CodeConstants.CONSTANT_Class, newname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cn;
|
||||
}
|
||||
// first dummy constant
|
||||
pool.add(null);
|
||||
|
||||
public LinkConstant getLinkConstant(int index) {
|
||||
LinkConstant ln = (LinkConstant)getConstant(index);
|
||||
|
||||
if(ln != null && interceptor != null) {
|
||||
if(ln.type == CodeConstants.CONSTANT_Fieldref ||
|
||||
ln.type == CodeConstants.CONSTANT_Methodref ||
|
||||
ln.type == CodeConstants.CONSTANT_InterfaceMethodref) {
|
||||
|
||||
String new_classname = buildNewClassname(ln.classname);
|
||||
String new_element = interceptor.getName(ln.classname+" "+ln.elementname+" "+ln.descriptor);
|
||||
String new_descriptor = buildNewDescriptor(ln.type, ln.descriptor);
|
||||
|
||||
if(new_classname != null || new_element != null || new_descriptor != null) {
|
||||
|
||||
ln = new LinkConstant(ln.type, new_classname==null?ln.classname:new_classname,
|
||||
new_element==null?ln.elementname:new_element.split(" ")[1],
|
||||
new_descriptor==null?ln.descriptor:new_descriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ln;
|
||||
}
|
||||
|
||||
private String buildNewClassname(String classname) {
|
||||
|
||||
VarType vt = new VarType(classname, true);
|
||||
|
||||
String newname = interceptor.getName(vt.value);
|
||||
if(newname != null) {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
|
||||
if(vt.arraydim > 0) {
|
||||
for(int i=0;i<vt.arraydim;i++) {
|
||||
buffer.append("[");
|
||||
}
|
||||
|
||||
buffer.append("L"+newname+";");
|
||||
} else {
|
||||
buffer.append(newname);
|
||||
}
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
// first pass: read the elements
|
||||
for (int i = 1; i < size; i++) {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private String buildNewDescriptor(int type, String descriptor) {
|
||||
byte tag = (byte)in.readUnsignedByte();
|
||||
|
||||
boolean updated = false;
|
||||
|
||||
if(type == CodeConstants.CONSTANT_Fieldref) {
|
||||
FieldDescriptor fd = FieldDescriptor.parseDescriptor(descriptor);
|
||||
switch (tag) {
|
||||
case CodeConstants.CONSTANT_Utf8:
|
||||
pool.add(new PrimitiveConstant(CodeConstants.CONSTANT_Utf8, in.readUTF()));
|
||||
break;
|
||||
case CodeConstants.CONSTANT_Integer:
|
||||
pool.add(new PrimitiveConstant(CodeConstants.CONSTANT_Integer, new Integer(in.readInt())));
|
||||
break;
|
||||
case CodeConstants.CONSTANT_Float:
|
||||
pool.add(new PrimitiveConstant(CodeConstants.CONSTANT_Float, new Float(in.readFloat())));
|
||||
break;
|
||||
case CodeConstants.CONSTANT_Long:
|
||||
pool.add(new PrimitiveConstant(CodeConstants.CONSTANT_Long, new Long(in.readLong())));
|
||||
pool.add(null);
|
||||
i++;
|
||||
break;
|
||||
case CodeConstants.CONSTANT_Double:
|
||||
pool.add(new PrimitiveConstant(CodeConstants.CONSTANT_Double, new Double(in.readDouble())));
|
||||
pool.add(null);
|
||||
i++;
|
||||
break;
|
||||
case CodeConstants.CONSTANT_Class:
|
||||
case CodeConstants.CONSTANT_String:
|
||||
case CodeConstants.CONSTANT_MethodType:
|
||||
pool.add(new PrimitiveConstant(tag, in.readUnsignedShort()));
|
||||
pass[i] = 1;
|
||||
break;
|
||||
case CodeConstants.CONSTANT_Fieldref:
|
||||
case CodeConstants.CONSTANT_Methodref:
|
||||
case CodeConstants.CONSTANT_InterfaceMethodref:
|
||||
case CodeConstants.CONSTANT_NameAndType:
|
||||
case CodeConstants.CONSTANT_InvokeDynamic:
|
||||
pool.add(new LinkConstant(tag, in.readUnsignedShort(), in.readUnsignedShort()));
|
||||
if (tag == CodeConstants.CONSTANT_NameAndType) {
|
||||
pass[i] = 1;
|
||||
}
|
||||
else {
|
||||
pass[i] = 2;
|
||||
}
|
||||
break;
|
||||
case CodeConstants.CONSTANT_MethodHandle:
|
||||
pool.add(new LinkConstant(tag, in.readUnsignedByte(), in.readUnsignedShort()));
|
||||
pass[i] = 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
VarType ftype = fd.type;
|
||||
if(ftype.type == CodeConstants.TYPE_OBJECT) {
|
||||
String newclname = buildNewClassname(ftype.value);
|
||||
if(newclname != null) {
|
||||
ftype.value = newclname;
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(updated) {
|
||||
return fd.getDescriptor();
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
MethodDescriptor md = MethodDescriptor.parseDescriptor(descriptor);
|
||||
// params
|
||||
for(VarType partype : md.params) {
|
||||
if(partype.type == CodeConstants.TYPE_OBJECT) {
|
||||
String newclname = buildNewClassname(partype.value);
|
||||
if(newclname != null) {
|
||||
partype.value = newclname;
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return value
|
||||
if(md.ret.type == CodeConstants.TYPE_OBJECT) {
|
||||
String newclname = buildNewClassname(md.ret.value);
|
||||
if(newclname!=null) {
|
||||
md.ret.value = newclname;
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(updated) {
|
||||
return md.getDescriptor();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// resolving complex pool elements
|
||||
for (int pass_index = 1; pass_index <= 3; pass_index++) {
|
||||
for (int i = 1; i < size; i++) {
|
||||
if (pass[i] == pass_index) {
|
||||
pool.get(i).resolveConstant(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get global constant pool interceptor instance, if any available
|
||||
interceptor = DecompilerContext.getPoolInterceptor();
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// public methods
|
||||
// *****************************************************************************
|
||||
|
||||
public void writeToOutputStream(DataOutputStream out) throws FileNotFoundException, IOException {
|
||||
|
||||
out.writeShort(pool.size());
|
||||
for (int i = 1; i < pool.size(); i++) {
|
||||
PooledConstant cnst = (PooledConstant)pool.get(i);
|
||||
if (cnst != null) {
|
||||
cnst.writeToStream(out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void skipPool(DataInputStream in) throws IOException {
|
||||
|
||||
int size = in.readUnsignedShort();
|
||||
|
||||
for (int i = 1; i < size; i++) {
|
||||
switch (in.readUnsignedByte()) {
|
||||
case CodeConstants.CONSTANT_Utf8:
|
||||
in.readUTF();
|
||||
break;
|
||||
case CodeConstants.CONSTANT_Integer:
|
||||
case CodeConstants.CONSTANT_Float:
|
||||
case CodeConstants.CONSTANT_Fieldref:
|
||||
case CodeConstants.CONSTANT_Methodref:
|
||||
case CodeConstants.CONSTANT_InterfaceMethodref:
|
||||
case CodeConstants.CONSTANT_NameAndType:
|
||||
case CodeConstants.CONSTANT_InvokeDynamic:
|
||||
in.skip(4);
|
||||
break;
|
||||
case CodeConstants.CONSTANT_Long:
|
||||
case CodeConstants.CONSTANT_Double:
|
||||
in.skip(8);
|
||||
i++;
|
||||
break;
|
||||
case CodeConstants.CONSTANT_Class:
|
||||
case CodeConstants.CONSTANT_String:
|
||||
case CodeConstants.CONSTANT_MethodType:
|
||||
in.skip(2);
|
||||
break;
|
||||
case CodeConstants.CONSTANT_MethodHandle:
|
||||
in.skip(3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return pool.size();
|
||||
}
|
||||
|
||||
public String[] getClassElement(int element_type, int class_index, int name_index, int descriptor_index) {
|
||||
|
||||
String classname = ((PrimitiveConstant)getConstant(class_index)).getString();
|
||||
String elementname = ((PrimitiveConstant)getConstant(name_index)).getString();
|
||||
String descriptor = ((PrimitiveConstant)getConstant(descriptor_index)).getString();
|
||||
|
||||
if (interceptor != null) {
|
||||
String new_element = interceptor.getName(classname + " " + elementname + " " + descriptor);
|
||||
|
||||
if (new_element != null) {
|
||||
elementname = new_element.split(" ")[1];
|
||||
}
|
||||
|
||||
String new_descriptor = buildNewDescriptor(element_type == FIELD ? CodeConstants.CONSTANT_Fieldref : CodeConstants.CONSTANT_Methodref,
|
||||
descriptor);
|
||||
if (new_descriptor != null) {
|
||||
descriptor = new_descriptor;
|
||||
}
|
||||
}
|
||||
|
||||
return new String[]{elementname, descriptor};
|
||||
}
|
||||
|
||||
public PooledConstant getConstant(int index) {
|
||||
return pool.get(index);
|
||||
}
|
||||
|
||||
public PrimitiveConstant getPrimitiveConstant(int index) {
|
||||
PrimitiveConstant cn = (PrimitiveConstant)getConstant(index);
|
||||
|
||||
if (cn != null && interceptor != null) {
|
||||
if (cn.type == CodeConstants.CONSTANT_Class) {
|
||||
String newname = buildNewClassname(cn.getString());
|
||||
if (newname != null) {
|
||||
cn = new PrimitiveConstant(CodeConstants.CONSTANT_Class, newname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cn;
|
||||
}
|
||||
|
||||
public LinkConstant getLinkConstant(int index) {
|
||||
LinkConstant ln = (LinkConstant)getConstant(index);
|
||||
|
||||
if (ln != null && interceptor != null) {
|
||||
if (ln.type == CodeConstants.CONSTANT_Fieldref ||
|
||||
ln.type == CodeConstants.CONSTANT_Methodref ||
|
||||
ln.type == CodeConstants.CONSTANT_InterfaceMethodref) {
|
||||
|
||||
String new_classname = buildNewClassname(ln.classname);
|
||||
String new_element = interceptor.getName(ln.classname + " " + ln.elementname + " " + ln.descriptor);
|
||||
String new_descriptor = buildNewDescriptor(ln.type, ln.descriptor);
|
||||
|
||||
if (new_classname != null || new_element != null || new_descriptor != null) {
|
||||
|
||||
ln = new LinkConstant(ln.type, new_classname == null ? ln.classname : new_classname,
|
||||
new_element == null ? ln.elementname : new_element.split(" ")[1],
|
||||
new_descriptor == null ? ln.descriptor : new_descriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ln;
|
||||
}
|
||||
|
||||
private String buildNewClassname(String classname) {
|
||||
|
||||
VarType vt = new VarType(classname, true);
|
||||
|
||||
String newname = interceptor.getName(vt.value);
|
||||
if (newname != null) {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
|
||||
if (vt.arraydim > 0) {
|
||||
for (int i = 0; i < vt.arraydim; i++) {
|
||||
buffer.append("[");
|
||||
}
|
||||
|
||||
buffer.append("L" + newname + ";");
|
||||
}
|
||||
else {
|
||||
buffer.append(newname);
|
||||
}
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private String buildNewDescriptor(int type, String descriptor) {
|
||||
|
||||
boolean updated = false;
|
||||
|
||||
if (type == CodeConstants.CONSTANT_Fieldref) {
|
||||
FieldDescriptor fd = FieldDescriptor.parseDescriptor(descriptor);
|
||||
|
||||
VarType ftype = fd.type;
|
||||
if (ftype.type == CodeConstants.TYPE_OBJECT) {
|
||||
String newclname = buildNewClassname(ftype.value);
|
||||
if (newclname != null) {
|
||||
ftype.value = newclname;
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (updated) {
|
||||
return fd.getDescriptor();
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
MethodDescriptor md = MethodDescriptor.parseDescriptor(descriptor);
|
||||
// params
|
||||
for (VarType partype : md.params) {
|
||||
if (partype.type == CodeConstants.TYPE_OBJECT) {
|
||||
String newclname = buildNewClassname(partype.value);
|
||||
if (newclname != null) {
|
||||
partype.value = newclname;
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return value
|
||||
if (md.ret.type == CodeConstants.TYPE_OBJECT) {
|
||||
String newclname = buildNewClassname(md.ret.value);
|
||||
if (newclname != null) {
|
||||
md.ret.value = newclname;
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (updated) {
|
||||
return md.getDescriptor();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user