public ClassNode(string content_class_name, string content_method_name, string content_method_descriptor , int content_method_invocation_type, string lambda_class_name, string lambda_method_name , string lambda_method_descriptor, StructClass classStruct) { // lambda class constructor this.type = Class_Lambda; this.classStruct = classStruct; // 'parent' class containing the static function lambdaInformation = new ClassesProcessor.ClassNode.LambdaInformation(); lambdaInformation.method_name = lambda_method_name; lambdaInformation.method_descriptor = lambda_method_descriptor; lambdaInformation.content_class_name = content_class_name; lambdaInformation.content_method_name = content_method_name; lambdaInformation.content_method_descriptor = content_method_descriptor; lambdaInformation.content_method_invocation_type = content_method_invocation_type; lambdaInformation.content_method_key = InterpreterUtil.MakeUniqueKey(lambdaInformation .content_method_name, lambdaInformation.content_method_descriptor); anonymousClassType = new VarType(lambda_class_name, true); bool is_method_reference = (content_class_name != classStruct.qualifiedName); if (!is_method_reference) { // content method in the same class, check synthetic flag StructMethod mt = classStruct.GetMethod(content_method_name, content_method_descriptor ); is_method_reference = !mt.IsSynthetic(); } // if not synthetic -> method reference lambdaInformation.is_method_reference = is_method_reference; lambdaInformation.is_content_method_static = (lambdaInformation.content_method_invocation_type == ICodeConstants.CONSTANT_MethodHandle_REF_invokeStatic); }
public virtual void InlineJsr(StructMethod mt) { ProcessJsr(); RemoveJsr(mt); RemoveMarkers(); DeadCodeHelper.RemoveEmptyBlocks(this); }
// node id, var, version //private HashMap<String, HashMap<Integer, FastSet<Integer>>> inVarVersions = new HashMap<String, HashMap<Integer, FastSet<Integer>>>(); // node id, var, version (direct branch) //private HashMap<String, HashMap<Integer, FastSet<Integer>>> outVarVersions = new HashMap<String, HashMap<Integer, FastSet<Integer>>>(); // node id, var, version (negative branch) //private HashMap<String, HashMap<Integer, FastSet<Integer>>> outNegVarVersions = new HashMap<String, HashMap<Integer, FastSet<Integer>>>(); // node id, var, version //private HashMap<String, HashMap<Integer, FastSet<Integer>>> extraVarVersions = new HashMap<String, HashMap<Integer, FastSet<Integer>>>(); // var, version // version, protected ranges (catch, finally) // version, version // ++ and -- // node.id, version, version // finally exits // versions memory dependencies // field access vars (exprent id, var id) // field access counter // set factory public virtual void SplitVariables(RootStatement root, StructMethod mt) { FlattenStatementsHelper flatthelper = new FlattenStatementsHelper(); DirectGraph dgraph = flatthelper.BuildDirectGraph(root); HashSet <int> setInit = new HashSet <int>(); for (int i = 0; i < 64; i++) { setInit.Add(i); } factory = new FastSparseSetFactory <int>(setInit); Sharpen.Collections.Put(extraVarVersions, dgraph.first.id, CreateFirstMap(mt, root )); SetCatchMaps(root, dgraph, flatthelper); // try { // DotExporter.toDotFile(dgraph, new File("c:\\Temp\\gr12_my.dot")); // } catch(Exception ex) {ex.printStackTrace();} HashSet <string> updated = new HashSet <string>(); do { // System.out.println("~~~~~~~~~~~~~ \r\n"+root.toJava()); SsaStatements(dgraph, updated, false); }while (!(updated.Count == 0)); // System.out.println("~~~~~~~~~~~~~ \r\n"+root.toJava()); SsaStatements(dgraph, updated, true); ssuversions.InitDominators(); }
private SFormsFastMapDirect CreateFirstMap(StructMethod mt, RootStatement root) { bool thisvar = !mt.HasModifier(ICodeConstants.Acc_Static); MethodDescriptor md = MethodDescriptor.ParseDescriptor(mt.GetDescriptor()); int paramcount = [email protected] + (thisvar ? 1 : 0); int varindex = 0; SFormsFastMapDirect map = new SFormsFastMapDirect(); for (int i = 0; i < paramcount; i++) { int version = GetNextFreeVersion(varindex, root); // == 1 FastSparseSetFactory <int> .FastSparseSet <int> set = factory.SpawnEmptySet(); set.Add(version); map.Put(varindex, set); ssuversions.CreateNode(new VarVersionPair(varindex, version)); if (thisvar) { if (i == 0) { varindex++; } else { varindex += md.@params[i - 1].stackSize; } } else { varindex += md.@params[i].stackSize; } } return(map); }
public MethodProcessorRunnable(StructMethod method, MethodDescriptor methodDescriptor , VarProcessor varProc, DecompilerContext parentContext) { this.method = method; this.methodDescriptor = methodDescriptor; this.varProc = varProc; this.parentContext = parentContext; }
public MethodWrapper(RootStatement root, VarProcessor varproc, StructMethod methodStruct , CounterContainer counter) { this.root = root; this.varproc = varproc; this.methodStruct = methodStruct; this.counter = counter; }
public ReadOnlyStructMethod(StructMethod method) { this.method = method; body = new ReadOnlyMethodBody(method.Body); genericParameters = ReadOnlyGenericParameterDeclaration.Create(method.GenericParameters); parameters = ReadOnlyMethodParameter.Create(method.Parameters); returnType = new ReadOnlyTypeReference(method.ReturnType); }
public static void ClearEnum(ClassWrapper wrapper) { StructClass cl = wrapper.GetClassStruct(); // hide values/valueOf methods and super() invocations foreach (MethodWrapper method in wrapper.GetMethods()) { StructMethod mt = method.methodStruct; string name = mt.GetName(); string descriptor = mt.GetDescriptor(); if ("values".Equals(name)) { if (descriptor.Equals("()[L" + cl.qualifiedName + ";")) { wrapper.GetHiddenMembers().Add(InterpreterUtil.MakeUniqueKey(name, descriptor)); } } else if ("valueOf".Equals(name)) { if (descriptor.Equals("(Ljava/lang/String;)L" + cl.qualifiedName + ";")) { wrapper.GetHiddenMembers().Add(InterpreterUtil.MakeUniqueKey(name, descriptor)); } } else if (ICodeConstants.Init_Name.Equals(name)) { Statement firstData = Statements.FindFirstData(method.root); if (firstData != null && !(firstData.GetExprents().Count == 0)) { Exprent exprent = firstData.GetExprents()[0]; if (exprent.type == Exprent.Exprent_Invocation) { InvocationExprent invExpr = (InvocationExprent)exprent; if (Statements.IsInvocationInitConstructor(invExpr, method, wrapper, false)) { firstData.GetExprents().RemoveAtReturningValue(0); } } } } } // hide synthetic fields of enum and it's constants foreach (StructField fd in cl.GetFields()) { string descriptor = fd.GetDescriptor(); if (fd.IsSynthetic() && descriptor.Equals("[L" + cl.qualifiedName + ";")) { wrapper.GetHiddenMembers().Add(InterpreterUtil.MakeUniqueKey(fd.GetName(), descriptor )); } } }
public static bool RemoveHardcodedChecks(Statement root, StructMethod mt) { bool checks_removed = false; // parameter @NotNull annotations while (FindAndRemoveParameterCheck(root, mt)) { // iterate until nothing found. Each invocation removes one parameter check. checks_removed = true; } // method @NotNull annotation while (FindAndRemoveReturnCheck(root, mt)) { // iterate until nothing found. Each invocation handles one method exit check. checks_removed = true; } return(checks_removed); }
public virtual string GetDebugName(StructMethod method) { StructLocalVariableTableAttribute attr = method.GetLocalVariableAttr(); if (attr != null && processor != null) { int?origIndex = processor.GetVarOriginalIndex(index); if (origIndex != null) { string name = attr.GetName(origIndex.Value, visibleOffset); if (name != null && TextUtil.IsValidIdentifier(name, method.GetClassStruct().GetBytecodeVersion ())) { return(name); } } } return(null); }
private static void MapClassMethods(ClassesProcessor.ClassNode node, Dictionary < ClassWrapper, MethodWrapper> map) { bool noSynthFlag = DecompilerContext.GetOption(IFernflowerPreferences.Synthetic_Not_Set ); ClassWrapper wrapper = node.GetWrapper(); foreach (MethodWrapper method in wrapper.GetMethods()) { StructMethod mt = method.methodStruct; if ((noSynthFlag || mt.IsSynthetic()) && mt.GetDescriptor().Equals("(Ljava/lang/String;)Ljava/lang/Class;" ) && mt.HasModifier(ICodeConstants.Acc_Static)) { RootStatement root = method.root; if (root != null && root.GetFirst().type == Statement.Type_Trycatch) { CatchStatement cst = (CatchStatement)root.GetFirst(); if (cst.GetStats().Count == 2 && cst.GetFirst().type == Statement.Type_Basicblock && cst.GetStats()[1].type == Statement.Type_Basicblock && cst.GetVars()[0].GetVarType ().Equals(new VarType(ICodeConstants.Type_Object, 0, "java/lang/ClassNotFoundException" ))) { BasicBlockStatement body = (BasicBlockStatement)cst.GetFirst(); BasicBlockStatement handler = (BasicBlockStatement)cst.GetStats()[1]; if (body.GetExprents().Count == 1 && handler.GetExprents().Count == 1) { if (Body_Expr.Equals(body.GetExprents()[0]) && Handler_Expr.Equals(handler.GetExprents ()[0])) { Sharpen.Collections.Put(map, wrapper, method); break; } } } } } } // iterate nested classes foreach (ClassesProcessor.ClassNode nd in node.nested) { MapClassMethods(nd, map); } }
private static bool FindAndRemoveReturnCheck(Statement stat, StructMethod mt) { bool is_notnull_check = false; // method annotation, refers to the return value StructAnnotationAttribute attr = mt.GetAttribute(StructGeneralAttribute.Attribute_Runtime_Invisible_Annotations ); if (attr != null) { List <AnnotationExprent> annotations = attr.GetAnnotations(); foreach (AnnotationExprent ann in annotations) { if (ann.GetClassName().Equals("org/jetbrains/annotations/NotNull")) { is_notnull_check = true; break; } } } return(is_notnull_check && RemoveReturnCheck(stat, mt)); }
public static DataPoint GetInitialDataPoint(StructMethod mt) { DataPoint point = new DataPoint(); MethodDescriptor md = MethodDescriptor.ParseDescriptor(mt.GetDescriptor()); int k = 0; if (!mt.HasModifier(ICodeConstants.Acc_Static)) { point.SetVariable(k++, new VarType(ICodeConstants.Type_Object, 0, null)); } for (int i = 0; i < [email protected]; i++) { VarType var = md.@params[i]; point.SetVariable(k++, var); if (var.stackSize == 2) { point.SetVariable(k++, new VarType(ICodeConstants.Type_Group2empty)); } } return(point); }
private bool IsVarArgCall() { StructClass cl = DecompilerContext.GetStructContext().GetClass(classname); if (cl != null) { StructMethod mt = cl.GetMethod(InterpreterUtil.MakeUniqueKey(name, stringDescriptor )); if (mt != null) { return(mt.HasModifier(ICodeConstants.Acc_Varargs)); } } else { // TODO: tap into IDEA indices to access libraries methods details // try to check the class on the classpath MethodInfo mtd = ClasspathHelper.FindMethod(classname, name, descriptor); return(mtd != null && mtd.GetParameters() .Any(param => Attribute.IsDefined(param, typeof(ParamArrayAttribute)))); } return(false); }
public static void ProcessClassReferences(ClassesProcessor.ClassNode node) { // find the synthetic method Class class$(String) if present Dictionary <ClassWrapper, MethodWrapper> mapClassMeths = new Dictionary <ClassWrapper , MethodWrapper>(); MapClassMethods(node, mapClassMeths); if ((mapClassMeths.Count == 0)) { return; } HashSet <ClassWrapper> setFound = new HashSet <ClassWrapper>(); ProcessClassRec(node, mapClassMeths, setFound); if (!(setFound.Count == 0)) { foreach (ClassWrapper wrp in setFound) { StructMethod mt = mapClassMeths.GetOrNull(wrp).methodStruct; wrp.GetHiddenMembers().Add(InterpreterUtil.MakeUniqueKey(mt.GetName(), mt.GetDescriptor ())); } } }
public virtual void SimplifyStackVars(RootStatement root, StructMethod mt, StructClass cl) { HashSet <int> setReorderedIfs = new HashSet <int>(); SSAUConstructorSparseEx ssau = null; while (true) { bool found = false; SSAConstructorSparseEx ssa = new SSAConstructorSparseEx(); ssa.SplitVariables(root, mt); SimplifyExprentsHelper sehelper = new SimplifyExprentsHelper(ssau == null); while (sehelper.SimplifyStackVarsStatement(root, setReorderedIfs, ssa, cl)) { found = true; } SetVersionsToNull(root); SequenceHelper.CondenseSequences(root); ssau = new SSAUConstructorSparseEx(); ssau.SplitVariables(root, mt); if (IterateStatements(root, ssau)) { found = true; } SetVersionsToNull(root); if (!found) { break; } } // remove unused assignments ssau = new SSAUConstructorSparseEx(); ssau.SplitVariables(root, mt); IterateStatements(root, ssau); SetVersionsToNull(root); }
public VarDefinitionHelper(Statement root, StructMethod mt, VarProcessor varproc) { // statement.id, defined vars mapVarDefStatements = new Dictionary <int, Statement>(); mapStatementVars = new Dictionary <int, HashSet <int> >(); implDefVars = new HashSet <int>(); this.varproc = varproc; VarNamesCollector vc = varproc.GetVarNamesCollector(); bool thisvar = !mt.HasModifier(ICodeConstants.Acc_Static); MethodDescriptor md = MethodDescriptor.ParseDescriptor(mt.GetDescriptor()); int paramcount = 0; if (thisvar) { paramcount = 1; } paramcount += [email protected]; // method parameters are implicitly defined int varindex = 0; for (int i = 0; i < paramcount; i++) { implDefVars.Add(varindex); varproc.SetVarName(new VarVersionPair(varindex, 0), vc.GetFreeName(varindex)); if (thisvar) { if (i == 0) { varindex++; } else { varindex += md.@params[i - 1].stackSize; } } else { varindex += md.@params[i].stackSize; } } if (thisvar) { StructClass current_class = (StructClass)DecompilerContext.GetProperty(DecompilerContext .Current_Class); Sharpen.Collections.Put(varproc.GetThisVars(), new VarVersionPair(0, 0), current_class .qualifiedName); varproc.SetVarName(new VarVersionPair(0, 0), "this"); vc.AddName("this"); } // catch variables are implicitly defined LinkedList <Statement> stack = new LinkedList <Statement>(); stack.AddLast(root); while (!(stack.Count == 0)) { Statement st = Sharpen.Collections.RemoveFirst(stack); List <VarExprent> lstVars = null; if (st.type == Statement.Type_Catchall) { lstVars = ((CatchAllStatement)st).GetVars(); } else if (st.type == Statement.Type_Trycatch) { lstVars = ((CatchStatement)st).GetVars(); } if (lstVars != null) { foreach (VarExprent var in lstVars) { implDefVars.Add(var.GetIndex()); varproc.SetVarName(new VarVersionPair(var), vc.GetFreeName(var.GetIndex())); var.SetDefinition(true); } } Sharpen.Collections.AddAll(stack, st.GetStats()); } InitStatement(root); }
private bool ProcessStatementEx(StructMethod mt, RootStatement root, ControlFlowGraph graph) { int bytecode_version = mt.GetClassStruct().GetBytecodeVersion(); LinkedList <Statement> stack = new LinkedList <Statement>(); stack.AddLast(root); while (!(stack.Count == 0)) { Statement stat = Sharpen.Collections.RemoveLast(stack); Statement parent = stat.GetParent(); if (parent != null && parent.type == Statement.Type_Catchall && stat == parent.GetFirst () && !parent.IsCopied()) { CatchAllStatement fin = (CatchAllStatement)parent; BasicBlock head = fin.GetBasichead().GetBlock(); BasicBlock handler = fin.GetHandler().GetBasichead().GetBlock(); if (catchallBlockIDs.ContainsKey(handler.id)) { } else if (finallyBlockIDs.ContainsKey(handler.id)) { // do nothing fin.SetFinally(true); int?var = finallyBlockIDs.GetOrNullable(handler.id); fin.SetMonitor(var == null ? null : new VarExprent(var.Value, VarType.Vartype_Int , varProcessor)); } else { FinallyProcessor.Record inf = GetFinallyInformation(mt, root, fin); if (inf == null) { // inconsistent finally Sharpen.Collections.Put(catchallBlockIDs, handler.id, null); } else { if (DecompilerContext.GetOption(IFernflowerPreferences.Finally_Deinline) && VerifyFinallyEx (graph, fin, inf)) { Sharpen.Collections.Put(finallyBlockIDs, handler.id, null); } else { int varindex = DecompilerContext.GetCounterContainer().GetCounterAndIncrement(CounterContainer .Var_Counter); InsertSemaphore(graph, GetAllBasicBlocks(fin.GetFirst()), head, handler, varindex , inf, bytecode_version); Sharpen.Collections.Put(finallyBlockIDs, handler.id, varindex); } DeadCodeHelper.RemoveDeadBlocks(graph); // e.g. multiple return blocks after a nested finally DeadCodeHelper.RemoveEmptyBlocks(graph); DeadCodeHelper.MergeBasicBlocks(graph); } return(true); } } Sharpen.Collections.AddAll(stack, stat.GetStats()); } return(false); }
public virtual bool IterateGraph(StructMethod mt, RootStatement root, ControlFlowGraph graph) { return(ProcessStatementEx(mt, root, graph)); }
public virtual byte[] LoadBytecode(StructMethod mt, int codeFullLength) { string className = mt.GetClassStruct().qualifiedName; try { using (DataInputFullStream @in = GetClassStream(className)) { if (@in != null) { @in.Discard(8); ConstantPool pool = mt.GetClassStruct().GetPool(); if (pool == null) { pool = new ConstantPool(@in); } else { ConstantPool.SkipPool(@in); } @in.Discard(6); // interfaces @in.Discard(@in.ReadUnsignedShort() * 2); // fields int size = @in.ReadUnsignedShort(); for (int i = 0; i < size; i++) { @in.Discard(6); SkipAttributes(@in); } // methods size = @in.ReadUnsignedShort(); for (int i = 0; i < size; i++) { @in.Discard(2); int nameIndex = @in.ReadUnsignedShort(); int descriptorIndex = @in.ReadUnsignedShort(); string[] values = pool.GetClassElement(ConstantPool.Method, className, nameIndex, descriptorIndex); if (!mt.GetName().Equals(values[0]) || !mt.GetDescriptor().Equals(values[1])) { SkipAttributes(@in); continue; } int attrSize = @in.ReadUnsignedShort(); for (int j = 0; j < attrSize; j++) { int attrNameIndex = @in.ReadUnsignedShort(); string attrName = pool.GetPrimitiveConstant(attrNameIndex).GetString(); if (!StructGeneralAttribute.Attribute_Code.GetName().Equals(attrName)) { @in.Discard(@in.ReadInt()); continue; } @in.Discard(12); return(@in.Read(codeFullLength)); } break; } } return(null); } } catch (IOException ex) { throw; } }
private void ComputeMethodType(ClassesProcessor.ClassNode node, MethodWrapper method ) { NestedMemberAccess.MethodAccess type = NestedMemberAccess.MethodAccess.Normal; if (method.root != null) { DirectGraph graph = method.GetOrBuildGraph(); StructMethod mt = method.methodStruct; if ((noSynthFlag || mt.IsSynthetic()) && mt.HasModifier(ICodeConstants.Acc_Static )) { if (graph.nodes.Count == 2) { // incl. dummy exit node if (graph.first.exprents.Count == 1) { Exprent exprent = graph.first.exprents[0]; MethodDescriptor mtdesc = MethodDescriptor.ParseDescriptor(mt.GetDescriptor()); int parcount = [email protected]; Exprent exprCore = exprent; if (exprent.type == Exprent.Exprent_Exit) { ExitExprent exexpr = (ExitExprent)exprent; if (exexpr.GetExitType() == ExitExprent.Exit_Return && exexpr.GetValue() != null) { exprCore = exexpr.GetValue(); } } switch (exprCore.type) { case Exprent.Exprent_Field: { FieldExprent fexpr = (FieldExprent)exprCore; if ((parcount == 1 && !fexpr.IsStatic()) || (parcount == 0 && fexpr.IsStatic())) { if (fexpr.GetClassname().Equals(node.classStruct.qualifiedName)) { // FIXME: check for private flag of the field if (fexpr.IsStatic() || (fexpr.GetInstance().type == Exprent.Exprent_Var && ((VarExprent )fexpr.GetInstance()).GetIndex() == 0)) { type = NestedMemberAccess.MethodAccess.Field_Get; } } } break; } case Exprent.Exprent_Var: { // qualified this if (parcount == 1) { // this or final variable if (((VarExprent)exprCore).GetIndex() != 0) { type = NestedMemberAccess.MethodAccess.Field_Get; } } break; } case Exprent.Exprent_Function: { // for now detect only increment/decrement FunctionExprent functionExprent = (FunctionExprent)exprCore; if (functionExprent.GetFuncType() >= FunctionExprent.Function_Imm && functionExprent .GetFuncType() <= FunctionExprent.Function_Ppi) { if (functionExprent.GetLstOperands()[0].type == Exprent.Exprent_Field) { type = NestedMemberAccess.MethodAccess.Function; } } break; } case Exprent.Exprent_Invocation: { type = NestedMemberAccess.MethodAccess.Method; break; } case Exprent.Exprent_Assignment: { AssignmentExprent asexpr = (AssignmentExprent)exprCore; if (asexpr.GetLeft().type == Exprent.Exprent_Field && asexpr.GetRight().type == Exprent .Exprent_Var) { FieldExprent fexpras = (FieldExprent)asexpr.GetLeft(); if ((parcount == 2 && !fexpras.IsStatic()) || (parcount == 1 && fexpras.IsStatic( ))) { if (fexpras.GetClassname().Equals(node.classStruct.qualifiedName)) { // FIXME: check for private flag of the field if (fexpras.IsStatic() || (fexpras.GetInstance().type == Exprent.Exprent_Var && ( (VarExprent)fexpras.GetInstance()).GetIndex() == 0)) { if (((VarExprent)asexpr.GetRight()).GetIndex() == parcount - 1) { type = NestedMemberAccess.MethodAccess.Field_Set; } } } } } break; } } if (type == NestedMemberAccess.MethodAccess.Method) { // FIXME: check for private flag of the method type = NestedMemberAccess.MethodAccess.Normal; InvocationExprent invexpr = (InvocationExprent)exprCore; bool isStatic = invexpr.IsStatic(); if ((isStatic && invexpr.GetLstParameters().Count == parcount) || (!isStatic && invexpr .GetInstance().type == Exprent.Exprent_Var && ((VarExprent)invexpr.GetInstance() ).GetIndex() == 0 && invexpr.GetLstParameters().Count == parcount - 1)) { bool equalpars = true; int index = isStatic ? 0 : 1; for (int i = 0; i < invexpr.GetLstParameters().Count; i++) { Exprent parexpr = invexpr.GetLstParameters()[i]; if (parexpr.type != Exprent.Exprent_Var || ((VarExprent)parexpr).GetIndex() != index) { equalpars = false; break; } index += mtdesc.@params[i + (isStatic ? 0 : 1)].stackSize; } if (equalpars) { type = NestedMemberAccess.MethodAccess.Method; } } } } else if (graph.first.exprents.Count == 2) { Exprent exprentFirst = graph.first.exprents[0]; Exprent exprentSecond = graph.first.exprents[1]; if (exprentFirst.type == Exprent.Exprent_Assignment && exprentSecond.type == Exprent .Exprent_Exit) { MethodDescriptor mtdesc = MethodDescriptor.ParseDescriptor(mt.GetDescriptor()); int parcount = [email protected]; AssignmentExprent asexpr = (AssignmentExprent)exprentFirst; if (asexpr.GetLeft().type == Exprent.Exprent_Field && asexpr.GetRight().type == Exprent .Exprent_Var) { FieldExprent fexpras = (FieldExprent)asexpr.GetLeft(); if ((parcount == 2 && !fexpras.IsStatic()) || (parcount == 1 && fexpras.IsStatic( ))) { if (fexpras.GetClassname().Equals(node.classStruct.qualifiedName)) { // FIXME: check for private flag of the field if (fexpras.IsStatic() || (fexpras.GetInstance().type == Exprent.Exprent_Var && ( (VarExprent)fexpras.GetInstance()).GetIndex() == 0)) { if (((VarExprent)asexpr.GetRight()).GetIndex() == parcount - 1) { ExitExprent exexpr = (ExitExprent)exprentSecond; if (exexpr.GetExitType() == ExitExprent.Exit_Return && exexpr.GetValue() != null) { if (exexpr.GetValue().type == Exprent.Exprent_Var && ((VarExprent)asexpr.GetRight ()).GetIndex() == parcount - 1) { type = NestedMemberAccess.MethodAccess.Field_Set; } } } } } } } } } } } } if (type != NestedMemberAccess.MethodAccess.Normal) { Sharpen.Collections.Put(mapMethodType, method, type); } else { Sharpen.Collections.Remove(mapMethodType, method); } }
private Exprent ReplaceAccessExprent(ClassesProcessor.ClassNode caller, MethodWrapper methdest, InvocationExprent invexpr) { ClassesProcessor.ClassNode node = DecompilerContext.GetClassProcessor().GetMapRootClasses ().GetOrNull(invexpr.GetClassname()); MethodWrapper methsource = null; if (node != null && node.GetWrapper() != null) { methsource = node.GetWrapper().GetMethodWrapper(invexpr.GetName(), invexpr.GetStringDescriptor ()); } if (methsource == null || !mapMethodType.ContainsKey(methsource)) { return(null); } // if same method, return if (node.classStruct.qualifiedName.Equals(caller.classStruct.qualifiedName) && methsource .methodStruct.GetName().Equals(methdest.methodStruct.GetName()) && methsource.methodStruct .GetDescriptor().Equals(methdest.methodStruct.GetDescriptor())) { // no recursive invocations permitted! return(null); } NestedMemberAccess.MethodAccess type = mapMethodType.GetOrNull(methsource); // // FIXME: impossible case. MethodAccess.NORMAL is not saved in the map // if(type == MethodAccess.NORMAL) { // return null; // } if (!SameTree(caller, node)) { return(null); } DirectGraph graph = methsource.GetOrBuildGraph(); Exprent source = graph.first.exprents[0]; Exprent retexprent = null; switch (type.ordinal()) { case 1: { ExitExprent exsource = (ExitExprent)source; if (exsource.GetValue().type == Exprent.Exprent_Var) { // qualified this VarExprent var = (VarExprent)exsource.GetValue(); string varname = methsource.varproc.GetVarName(new VarVersionPair(var)); if (!methdest.setOuterVarNames.Contains(varname)) { VarNamesCollector vnc = new VarNamesCollector(); vnc.AddName(varname); methdest.varproc.RefreshVarNames(vnc); methdest.setOuterVarNames.Add(varname); } int index = methdest.counter.GetCounterAndIncrement(CounterContainer.Var_Counter); VarExprent ret = new VarExprent(index, var.GetVarType(), methdest.varproc); methdest.varproc.SetVarName(new VarVersionPair(index, 0), varname); retexprent = ret; } else { // field FieldExprent ret = (FieldExprent)exsource.GetValue().Copy(); if (!ret.IsStatic()) { ret.ReplaceExprent(ret.GetInstance(), invexpr.GetLstParameters()[0]); } retexprent = ret; } break; } case 2: { AssignmentExprent ret_1; if (source.type == Exprent.Exprent_Exit) { ExitExprent extex = (ExitExprent)source; ret_1 = (AssignmentExprent)extex.GetValue().Copy(); } else { ret_1 = (AssignmentExprent)source.Copy(); } FieldExprent fexpr = (FieldExprent)ret_1.GetLeft(); if (fexpr.IsStatic()) { ret_1.ReplaceExprent(ret_1.GetRight(), invexpr.GetLstParameters()[0]); } else { ret_1.ReplaceExprent(ret_1.GetRight(), invexpr.GetLstParameters()[1]); fexpr.ReplaceExprent(fexpr.GetInstance(), invexpr.GetLstParameters()[0]); } // do not use copied bytecodes ret_1.GetLeft().bytecode = null; ret_1.GetRight().bytecode = null; retexprent = ret_1; break; } case 4: { retexprent = ReplaceFunction(invexpr, source); break; } case 3: { if (source.type == Exprent.Exprent_Exit) { source = ((ExitExprent)source).GetValue(); } InvocationExprent invret = (InvocationExprent)source.Copy(); int index_1 = 0; if (!invret.IsStatic()) { invret.ReplaceExprent(invret.GetInstance(), invexpr.GetLstParameters()[0]); index_1 = 1; } for (int i = 0; i < invret.GetLstParameters().Count; i++) { invret.ReplaceExprent(invret.GetLstParameters()[i], invexpr.GetLstParameters()[i + index_1]); } retexprent = invret; break; } } if (retexprent != null) { // preserve original bytecodes retexprent.bytecode = null; retexprent.AddBytecodeOffsets(invexpr.bytecode); // hide synthetic access method bool hide = true; if (node.type == ClassesProcessor.ClassNode.Class_Root || (node.access & ICodeConstants .Acc_Static) != 0) { StructMethod mt = methsource.methodStruct; if (!mt.IsSynthetic()) { hide = false; } } if (hide) { node.GetWrapper().GetHiddenMembers().Add(InterpreterUtil.MakeUniqueKey(invexpr.GetName (), invexpr.GetStringDescriptor())); } } return(retexprent); }
private static bool FindAndRemoveParameterCheck(Statement stat, StructMethod mt) { Statement st = stat.GetFirst(); while (st.type == Statement.Type_Sequence) { st = st.GetFirst(); } if (st.type == Statement.Type_If) { IfStatement ifstat = (IfStatement)st; Statement ifbranch = ifstat.GetIfstat(); Exprent if_condition = ifstat.GetHeadexprent().GetCondition(); bool is_notnull_check = false; // TODO: FUNCTION_NE also possible if reversed order (in theory) if (ifbranch != null && if_condition.type == Exprent.Exprent_Function && ((FunctionExprent )if_condition).GetFuncType() == FunctionExprent.Function_Eq && ifbranch.type == Statement.Type_Basicblock && ifbranch.GetExprents().Count == 1 && ifbranch.GetExprents ()[0].type == Exprent.Exprent_Exit) { FunctionExprent func = (FunctionExprent)if_condition; Exprent first_param = func.GetLstOperands()[0]; Exprent second_param = func.GetLstOperands()[1]; if (second_param.type == Exprent.Exprent_Const && second_param.GetExprType().type == ICodeConstants.Type_Null) { // TODO: reversed parameter order if (first_param.type == Exprent.Exprent_Var) { VarExprent var = (VarExprent)first_param; bool thisvar = !mt.HasModifier(ICodeConstants.Acc_Static); MethodDescriptor md = MethodDescriptor.ParseDescriptor(mt.GetDescriptor()); // parameter annotations StructAnnotationParameterAttribute param_annotations = mt.GetAttribute(StructGeneralAttribute .Attribute_Runtime_Invisible_Parameter_Annotations); if (param_annotations != null) { List <List <AnnotationExprent> > param_annotations_lists = param_annotations.GetParamAnnotations (); int method_param_number = [email protected]; int index = thisvar ? 1 : 0; for (int i = 0; i < method_param_number; i++) { if (index == var.GetIndex()) { if (param_annotations_lists.Count >= method_param_number - i) { int shift = method_param_number - param_annotations_lists.Count; // NOTE: workaround for compiler bug, count annotations starting with the last parameter List <AnnotationExprent> annotations = param_annotations_lists[i - shift]; foreach (AnnotationExprent ann in annotations) { if (ann.GetClassName().Equals("org/jetbrains/annotations/NotNull")) { is_notnull_check = true; break; } } } break; } index += md.@params[i].stackSize; } } } } } if (!is_notnull_check) { return(false); } RemoveParameterCheck(stat); return(true); } return(false); }
private static bool RemoveReturnCheck(Statement stat, StructMethod mt) { Statement parent = stat.GetParent(); if (parent != null && parent.type == Statement.Type_If && stat.type == Statement. Type_Basicblock && stat.GetExprents().Count == 1) { Exprent exprent = stat.GetExprents()[0]; if (exprent.type == Exprent.Exprent_Exit) { ExitExprent exit_exprent = (ExitExprent)exprent; if (exit_exprent.GetExitType() == ExitExprent.Exit_Return) { Exprent exprent_value = exit_exprent.GetValue(); //if(exprent_value.type == Exprent.EXPRENT_VAR) { // VarExprent var_value = (VarExprent)exprent_value; IfStatement ifparent = (IfStatement)parent; Exprent if_condition = ifparent.GetHeadexprent().GetCondition(); if (ifparent.GetElsestat() == stat && if_condition.type == Exprent.Exprent_Function && ((FunctionExprent)if_condition).GetFuncType() == FunctionExprent.Function_Eq) { // TODO: reversed order possible (in theory) FunctionExprent func = (FunctionExprent)if_condition; Exprent first_param = func.GetLstOperands()[0]; Exprent second_param = func.GetLstOperands()[1]; StatEdge ifedge = ifparent.GetIfEdge(); StatEdge elseedge = ifparent.GetElseEdge(); Statement ifbranch = ifparent.GetIfstat(); Statement elsebranch = ifparent.GetElsestat(); if (second_param.type == Exprent.Exprent_Const && second_param.GetExprType().type == ICodeConstants.Type_Null) { // TODO: reversed parameter order //if(first_param.type == Exprent.EXPRENT_VAR && ((VarExprent)first_param).getIndex() == var_value.getIndex()) { if (first_param.Equals(exprent_value)) { // TODO: check for absence of side effects like method invocations etc. if (ifbranch.type == Statement.Type_Basicblock && ifbranch.GetExprents().Count == 1 && ifbranch.GetExprents()[0].type == Exprent.Exprent_Exit) { // TODO: special check for IllegalStateException ifparent.GetFirst().RemoveSuccessor(ifedge); ifparent.GetFirst().RemoveSuccessor(elseedge); ifparent.GetStats().RemoveWithKey(ifbranch.id); ifparent.GetStats().RemoveWithKey(elsebranch.id); if (!(ifbranch.GetAllSuccessorEdges().Count == 0)) { ifbranch.RemoveSuccessor(ifbranch.GetAllSuccessorEdges()[0]); } if (!(ifparent.GetFirst().GetExprents().Count == 0)) { elsebranch.GetExprents().InsertRange(0, ifparent.GetFirst().GetExprents()); } ifparent.GetParent().ReplaceStatement(ifparent, elsebranch); ifparent.GetParent().SetAllParent(); return(true); } } } } } } } else if (parent != null && parent.type == Statement.Type_Sequence && stat.type == Statement.Type_Basicblock && stat.GetExprents().Count == 1) { //} Exprent exprent = stat.GetExprents()[0]; if (exprent.type == Exprent.Exprent_Exit) { ExitExprent exit_exprent = (ExitExprent)exprent; if (exit_exprent.GetExitType() == ExitExprent.Exit_Return) { Exprent exprent_value = exit_exprent.GetValue(); SequenceStatement sequence = (SequenceStatement)parent; int sequence_stats_number = sequence.GetStats().Count; if (sequence_stats_number > 1 && sequence.GetStats().GetLast() == stat && sequence .GetStats()[sequence_stats_number - 2].type == Statement.Type_If) { IfStatement ifstat = (IfStatement)sequence.GetStats()[sequence_stats_number - 2]; Exprent if_condition = ifstat.GetHeadexprent().GetCondition(); if (ifstat.iftype == IfStatement.Iftype_If && if_condition.type == Exprent.Exprent_Function && ((FunctionExprent)if_condition).GetFuncType() == FunctionExprent.Function_Eq) { // TODO: reversed order possible (in theory) FunctionExprent func = (FunctionExprent)if_condition; Exprent first_param = func.GetLstOperands()[0]; Exprent second_param = func.GetLstOperands()[1]; Statement ifbranch = ifstat.GetIfstat(); if (second_param.type == Exprent.Exprent_Const && second_param.GetExprType().type == ICodeConstants.Type_Null) { // TODO: reversed parameter order if (first_param.Equals(exprent_value)) { // TODO: check for absence of side effects like method invocations etc. if (ifbranch.type == Statement.Type_Basicblock && ifbranch.GetExprents().Count == 1 && ifbranch.GetExprents()[0].type == Exprent.Exprent_Exit) { // TODO: special check for IllegalStateException ifstat.RemoveSuccessor(ifstat.GetAllSuccessorEdges()[0]); // remove 'else' edge if (!(ifstat.GetFirst().GetExprents().Count == 0)) { stat.GetExprents().InsertRange(0, ifstat.GetFirst().GetExprents()); } foreach (StatEdge edge in ifstat.GetAllPredecessorEdges()) { ifstat.RemovePredecessor(edge); edge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, edge, stat); stat.AddPredecessor(edge); } sequence.GetStats().RemoveWithKey(ifstat.id); sequence.SetFirst(sequence.GetStats()[0]); return(true); } } } } } } } } foreach (Statement st in stat.GetStats()) { if (RemoveReturnCheck(st, mt)) { return(true); } } return(false); }
private BitSet GetAmbiguousParameters() { StructClass cl = DecompilerContext.GetStructContext().GetClass(classname); if (cl == null) { return(Empty_Bit_Set); } // check number of matches List <MethodDescriptor> matches = new List <MethodDescriptor>(); foreach (StructMethod mt in cl.GetMethods()) { if (name.Equals(mt.GetName())) { MethodDescriptor md = MethodDescriptor.ParseDescriptor(mt.GetDescriptor()); if ([email protected] == [email protected]) { for (int i = 0; i < [email protected]; i++) { if (md.@params[i].typeFamily != descriptor.@params[i].typeFamily) { goto nextMethod_continue; } } matches.Add(md); } } } nextMethod_break :; nextMethod_continue : if (matches.Count == 1) { return(Empty_Bit_Set); } // check if a call is unambiguous StructMethod mt_1 = cl.GetMethod(InterpreterUtil.MakeUniqueKey(name, stringDescriptor )); if (mt_1 != null) { MethodDescriptor md = MethodDescriptor.ParseDescriptor(mt_1.GetDescriptor()); if ([email protected] == lstParameters.Count) { bool exact = true; for (int i = 0; i < [email protected]; i++) { if (!md.@params[i].Equals(lstParameters[i].GetExprType())) { exact = false; break; } } if (exact) { return(Empty_Bit_Set); } } } // mark parameters BitSet ambiguous = new BitSet([email protected]); for (int i = 0; i < [email protected]; i++) { VarType paramType = descriptor.@params[i]; foreach (MethodDescriptor md in matches) { if (!paramType.Equals(md.@params[i])) { ambiguous.Set(i); break; } } } return(ambiguous); }
public VarVersionsProcessor(StructMethod mt, MethodDescriptor md) { method = mt; typeProcessor = new VarTypeProcessor(mt, md); }
public VarProcessor(StructMethod mt, MethodDescriptor md) { method = mt; methodDescriptor = md; }
private FinallyProcessor.Record GetFinallyInformation(StructMethod mt, RootStatement root, CatchAllStatement fstat) { Dictionary <BasicBlock, bool> mapLast = new Dictionary <BasicBlock, bool>(); BasicBlockStatement firstBlockStatement = fstat.GetHandler().GetBasichead(); BasicBlock firstBasicBlock = firstBlockStatement.GetBlock(); Instruction instrFirst = firstBasicBlock.GetInstruction(0); int firstcode = 0; switch (instrFirst.opcode) { case ICodeConstants.opc_pop: { firstcode = 1; break; } case ICodeConstants.opc_astore: { firstcode = 2; break; } } ExprProcessor proc = new ExprProcessor(methodDescriptor, varProcessor); proc.ProcessStatement(root, mt.GetClassStruct()); SSAConstructorSparseEx ssa = new SSAConstructorSparseEx(); ssa.SplitVariables(root, mt); List <Exprent> lstExprents = firstBlockStatement.GetExprents(); VarVersionPair varpaar = new VarVersionPair((VarExprent)((AssignmentExprent)lstExprents [firstcode == 2 ? 1 : 0]).GetLeft()); FlattenStatementsHelper flatthelper = new FlattenStatementsHelper(); DirectGraph dgraph = flatthelper.BuildDirectGraph(root); LinkedList <DirectNode> stack = new LinkedList <DirectNode>(); stack.AddLast(dgraph.first); HashSet <DirectNode> setVisited = new HashSet <DirectNode>(); while (!(stack.Count == 0)) { DirectNode node = Sharpen.Collections.RemoveFirst(stack); if (setVisited.Contains(node)) { continue; } setVisited.Add(node); BasicBlockStatement blockStatement = null; if (node.block != null) { blockStatement = node.block; } else if (node.preds.Count == 1) { blockStatement = node.preds[0].block; } bool isTrueExit = true; if (firstcode != 1) { isTrueExit = false; for (int i = 0; i < node.exprents.Count; i++) { Exprent exprent = node.exprents[i]; if (firstcode == 0) { List <Exprent> lst = exprent.GetAllExprents(); lst.Add(exprent); bool found = false; foreach (Exprent expr in lst) { if (expr.type == Exprent.Exprent_Var && new VarVersionPair((VarExprent)expr).Equals (varpaar)) { found = true; break; } } if (found) { found = false; if (exprent.type == Exprent.Exprent_Exit) { ExitExprent exexpr = (ExitExprent)exprent; if (exexpr.GetExitType() == ExitExprent.Exit_Throw && exexpr.GetValue().type == Exprent .Exprent_Var) { found = true; } } if (!found) { return(null); } else { isTrueExit = true; } } } else if (firstcode == 2) { // search for a load instruction if (exprent.type == Exprent.Exprent_Assignment) { AssignmentExprent assexpr = (AssignmentExprent)exprent; if (assexpr.GetRight().type == Exprent.Exprent_Var && new VarVersionPair((VarExprent )assexpr.GetRight()).Equals(varpaar)) { Exprent next = null; if (i == node.exprents.Count - 1) { if (node.succs.Count == 1) { DirectNode nd = node.succs[0]; if (!(nd.exprents.Count == 0)) { next = nd.exprents[0]; } } } else { next = node.exprents[i + 1]; } bool found = false; if (next != null && next.type == Exprent.Exprent_Exit) { ExitExprent exexpr = (ExitExprent)next; if (exexpr.GetExitType() == ExitExprent.Exit_Throw && exexpr.GetValue().type == Exprent .Exprent_Var && assexpr.GetLeft().Equals(exexpr.GetValue())) { found = true; } } if (!found) { return(null); } else { isTrueExit = true; } } } } } } // find finally exits if (blockStatement != null && blockStatement.GetBlock() != null) { Statement handler = fstat.GetHandler(); foreach (StatEdge edge in blockStatement.GetSuccessorEdges(Statement.Statedge_Direct_All )) { if (edge.GetType() != StatEdge.Type_Regular && handler.ContainsStatement(blockStatement ) && !handler.ContainsStatement(edge.GetDestination())) { bool?existingFlag = mapLast.GetOrNullable(blockStatement.GetBlock()); // note: the dummy node is also processed! if (existingFlag == null || !existingFlag.Value) { Sharpen.Collections.Put(mapLast, blockStatement.GetBlock(), isTrueExit); break; } } } } Sharpen.Collections.AddAll(stack, node.succs); } // empty finally block? if (fstat.GetHandler().type == Statement.Type_Basicblock) { bool isEmpty = false; bool isFirstLast = mapLast.ContainsKey(firstBasicBlock); InstructionSequence seq = firstBasicBlock.GetSeq(); switch (firstcode) { case 0: { isEmpty = isFirstLast && seq.Length() == 1; break; } case 1: { isEmpty = seq.Length() == 1; break; } case 2: { isEmpty = isFirstLast ? seq.Length() == 3 : seq.Length() == 1; break; } } if (isEmpty) { firstcode = 3; } } return(new FinallyProcessor.Record(firstcode, mapLast)); }
private static void SimpleMerge(VarTypeProcessor typeProcessor, DirectGraph graph , StructMethod mt) { Dictionary <VarVersionPair, VarType> mapExprentMaxTypes = typeProcessor.GetMapExprentMaxTypes (); Dictionary <VarVersionPair, VarType> mapExprentMinTypes = typeProcessor.GetMapExprentMinTypes (); Dictionary <int, HashSet <int> > mapVarVersions = new Dictionary <int, HashSet <int> > (); foreach (VarVersionPair pair in mapExprentMinTypes.Keys) { if (pair.version >= 0) { // don't merge constants mapVarVersions.ComputeIfAbsent(pair.var, (int k) => new HashSet <int>()).Add(pair. version); } } bool is_method_static = mt.HasModifier(ICodeConstants.Acc_Static); Dictionary <VarVersionPair, int> mapMergedVersions = new Dictionary <VarVersionPair , int>(); foreach (KeyValuePair <int, HashSet <int> > ent in mapVarVersions) { if (ent.Value.Count > 1) { List <int> lstVersions = new List <int>(ent.Value); lstVersions.Sort(); for (int i = 0; i < lstVersions.Count; i++) { VarVersionPair firstPair = new VarVersionPair(ent.Key, lstVersions[i]); VarType firstType = mapExprentMinTypes.GetOrNull(firstPair); if (firstPair.var == 0 && firstPair.version == 1 && !is_method_static) { continue; } // don't merge 'this' variable for (int j = i + 1; j < lstVersions.Count; j++) { VarVersionPair secondPair = new VarVersionPair(ent.Key, lstVersions[j]); VarType secondType = mapExprentMinTypes.GetOrNull(secondPair); if (firstType.Equals(secondType) || (firstType.Equals(VarType.Vartype_Null) && secondType .type == ICodeConstants.Type_Object) || (secondType.Equals(VarType.Vartype_Null) && firstType.type == ICodeConstants.Type_Object)) { VarType firstMaxType = mapExprentMaxTypes.GetOrNull(firstPair); VarType secondMaxType = mapExprentMaxTypes.GetOrNull(secondPair); VarType type = firstMaxType == null ? secondMaxType : secondMaxType == null ? firstMaxType : VarType.GetCommonMinType(firstMaxType, secondMaxType); Sharpen.Collections.Put(mapExprentMaxTypes, firstPair, type); Sharpen.Collections.Put(mapMergedVersions, secondPair, firstPair.version); Sharpen.Collections.Remove(mapExprentMaxTypes, secondPair); Sharpen.Collections.Remove(mapExprentMinTypes, secondPair); if (firstType.Equals(VarType.Vartype_Null)) { Sharpen.Collections.Put(mapExprentMinTypes, firstPair, secondType); firstType = secondType; } Sharpen.Collections.Put(typeProcessor.GetMapFinalVars(), firstPair, VarTypeProcessor .Var_Non_Final); lstVersions.RemoveAtReturningValue(j); //noinspection AssignmentToForLoopParameter j--; } } } } } if (!(mapMergedVersions.Count == 0)) { UpdateVersions(graph, mapMergedVersions); } }
private void RenameClassIdentifiers(StructClass cl, Dictionary <string, string> names ) { // all classes are already renamed string classOldFullName = cl.qualifiedName; string classNewFullName = interceptor.GetName(classOldFullName); if (classNewFullName == null) { classNewFullName = classOldFullName; } // methods HashSet <string> setMethodNames = new HashSet <string>(); foreach (StructMethod md in cl.GetMethods()) { setMethodNames.Add(md.GetName()); } VBStyleCollection <StructMethod, string> methods = cl.GetMethods(); for (int i = 0; i < methods.Count; i++) { StructMethod mt = methods[i]; string key = methods.GetKey(i); bool isPrivate = mt.HasModifier(ICodeConstants.Acc_Private); string name = mt.GetName(); if (!cl.IsOwn() || mt.HasModifier(ICodeConstants.Acc_Native)) { // external and native methods must not be renamed if (!isPrivate) { Sharpen.Collections.Put(names, key, name); } } else if (helper.ToBeRenamed(IIdentifierRenamer.Type.Element_Method, classOldFullName , name, mt.GetDescriptor())) { if (isPrivate || !names.ContainsKey(key)) { do { name = helper.GetNextMethodName(classOldFullName, name, mt.GetDescriptor()); }while (setMethodNames.Contains(name)); if (!isPrivate) { Sharpen.Collections.Put(names, key, name); } } else { name = names.GetOrNull(key); } interceptor.AddName(classOldFullName + " " + mt.GetName() + " " + mt.GetDescriptor (), classNewFullName + " " + name + " " + BuildNewDescriptor(false, mt.GetDescriptor ())); } } // external fields are not being renamed if (!cl.IsOwn()) { return; } // fields // FIXME: should overloaded fields become the same name? HashSet <string> setFieldNames = new HashSet <string>(); foreach (StructField fd in cl.GetFields()) { setFieldNames.Add(fd.GetName()); } foreach (StructField fd in cl.GetFields()) { if (helper.ToBeRenamed(IIdentifierRenamer.Type.Element_Field, classOldFullName, fd .GetName(), fd.GetDescriptor())) { string newName; do { newName = helper.GetNextFieldName(classOldFullName, fd.GetName(), fd.GetDescriptor ()); }while (setFieldNames.Contains(newName)); interceptor.AddName(classOldFullName + " " + fd.GetName() + " " + fd.GetDescriptor (), classNewFullName + " " + newName + " " + BuildNewDescriptor(true, fd.GetDescriptor ())); } } }