private static bool CollapseInlinedClass14(Statement stat) { bool ret = class14Builder.Match(stat); if (ret) { string class_name = (string)class14Builder.GetVariableValue("$classname$"); AssignmentExprent assignment = (AssignmentExprent)class14Builder.GetVariableValue ("$assignfield$"); FieldExprent fieldExpr = (FieldExprent)class14Builder.GetVariableValue("$field$"); assignment.ReplaceExprent(assignment.GetRight(), new ConstExprent(VarType.Vartype_Class , class_name, null)); List <Exprent> data = new List <Exprent>(stat.GetFirst().GetExprents()); stat.SetExprents(data); SequenceHelper.DestroyAndFlattenStatement(stat); ClassWrapper wrapper = (ClassWrapper)DecompilerContext.GetProperty(DecompilerContext .Current_Class_Wrapper); if (wrapper != null) { wrapper.GetHiddenMembers().Add(InterpreterUtil.MakeUniqueKey(fieldExpr.GetName(), fieldExpr.GetDescriptor().descriptorString)); } } return(ret); }
public static void WriteQualifiedSuper(TextBuffer buf, string qualifier) { ClassesProcessor.ClassNode classNode = (ClassesProcessor.ClassNode)DecompilerContext .GetProperty(DecompilerContext.Current_Class_Node); if (!qualifier.Equals(classNode.classStruct.qualifiedName)) { buf.Append(DecompilerContext.GetImportCollector().GetShortName(ExprProcessor.BuildJavaClassName (qualifier))).Append('.'); } buf.Append("super"); }
private void AppendDefinitionType(TextBuffer buffer) { if (DecompilerContext.GetOption(IFernflowerPreferences.Use_Debug_Var_Names)) { MethodWrapper method = (MethodWrapper)DecompilerContext.GetProperty(DecompilerContext .Current_Method_Wrapper); if (method != null) { int?originalIndex = null; if (processor != null) { originalIndex = processor.GetVarOriginalIndex(index); } if (originalIndex != null) { // first try from signature if (DecompilerContext.GetOption(IFernflowerPreferences.Decompile_Generic_Signatures )) { StructLocalVariableTypeTableAttribute attr = method.methodStruct.GetAttribute(StructGeneralAttribute .Attribute_Local_Variable_Type_Table); if (attr != null) { string signature = attr.GetSignature(originalIndex, visibleOffset); if (signature != null) { GenericFieldDescriptor descriptor = GenericMain.ParseFieldSignature(signature); if (descriptor != null) { buffer.Append(GenericMain.GetGenericCastTypeName(descriptor.type)); return; } } } } // then try from descriptor StructLocalVariableTableAttribute attr_1 = method.methodStruct.GetLocalVariableAttr (); if (attr_1 != null) { string descriptor = attr_1.GetDescriptor(originalIndex, visibleOffset); if (descriptor != null) { buffer.Append(ExprProcessor.GetCastTypeName(new VarType(descriptor))); return; } } } } } buffer.Append(ExprProcessor.GetCastTypeName(GetVarType())); }
private void SetInitVars(RootStatement root) { bool thisVar = !method.HasModifier(ICodeConstants.Acc_Static); MethodDescriptor md = methodDescriptor; if (thisVar) { StructClass cl = (StructClass)DecompilerContext.GetProperty(DecompilerContext.Current_Class ); VarType clType = new VarType(ICodeConstants.Type_Object, 0, cl.qualifiedName); Sharpen.Collections.Put(mapExprentMinTypes, new VarVersionPair(0, 1), clType); Sharpen.Collections.Put(mapExprentMaxTypes, new VarVersionPair(0, 1), clType); } int varIndex = 0; for (int i = 0; i < [email protected]; i++) { Sharpen.Collections.Put(mapExprentMinTypes, new VarVersionPair(varIndex + (thisVar ? 1 : 0), 1), md.@params[i]); Sharpen.Collections.Put(mapExprentMaxTypes, new VarVersionPair(varIndex + (thisVar ? 1 : 0), 1), md.@params[i]); varIndex += md.@params[i].stackSize; } // catch variables LinkedList <Statement> stack = new LinkedList <Statement>(); stack.AddLast(root); while (!(stack.Count == 0)) { Statement stat = Sharpen.Collections.RemoveFirst(stack); List <VarExprent> lstVars = null; if (stat.type == Statement.Type_Catchall) { lstVars = ((CatchAllStatement)stat).GetVars(); } else if (stat.type == Statement.Type_Trycatch) { lstVars = ((CatchStatement)stat).GetVars(); } if (lstVars != null) { foreach (VarExprent var in lstVars) { Sharpen.Collections.Put(mapExprentMinTypes, new VarVersionPair(var.GetIndex(), 1) , var.GetVarType()); Sharpen.Collections.Put(mapExprentMaxTypes, new VarVersionPair(var.GetIndex(), 1) , var.GetVarType()); } } Sharpen.Collections.AddAll(stack, stat.GetStats()); } }
public static string GetIndentString(int length) { if (length == 0) { return(string.Empty); } StringBuilder buf = new StringBuilder(); string indent = (string)DecompilerContext.GetProperty(IFernflowerPreferences.Indent_String ); Append(buf, indent, length); return(buf.ToString()); }
public override TextBuffer ToJava(int indent, BytecodeMappingTracer tracer) { tracer.AddMapping(bytecode); if (exitType == Exit_Return) { TextBuffer buffer = new TextBuffer("return"); if (retType.type != ICodeConstants.Type_Void) { buffer.Append(' '); ExprProcessor.GetCastedExprent(value, retType, buffer, indent, false, tracer); } return(buffer); } else { MethodWrapper method = (MethodWrapper)DecompilerContext.GetProperty(DecompilerContext .Current_Method_Wrapper); ClassesProcessor.ClassNode node = ((ClassesProcessor.ClassNode)DecompilerContext. GetProperty(DecompilerContext.Current_Class_Node)); if (method != null && node != null) { StructExceptionsAttribute attr = method.methodStruct.GetAttribute(StructGeneralAttribute .Attribute_Exceptions); if (attr != null) { string classname = null; for (int i = 0; i < attr.GetThrowsExceptions().Count; i++) { string exClassName = attr.GetExcClassname(i, node.classStruct.GetPool()); if ("java/lang/Throwable".Equals(exClassName)) { classname = exClassName; break; } else if ("java/lang/Exception".Equals(exClassName)) { classname = exClassName; } } if (classname != null) { VarType exType = new VarType(classname, true); TextBuffer buffer = new TextBuffer("throw "); ExprProcessor.GetCastedExprent(value, exType, buffer, indent, false, tracer); return(buffer); } } } return(value.ToJava(indent, tracer).Prepend("throw ")); } }
private bool IsAmbiguous() { MethodWrapper method = (MethodWrapper)DecompilerContext.GetProperty(DecompilerContext .Current_Method_Wrapper); if (method != null) { StructLocalVariableTableAttribute attr = method.methodStruct.GetLocalVariableAttr (); if (attr != null) { return(attr.ContainsName(name)); } } return(false); }
private static string GetQualifiedNewInstance(string classname, List <Exprent> lstParams , int indent, BytecodeMappingTracer tracer) { ClassesProcessor.ClassNode node = DecompilerContext.GetClassProcessor().GetMapRootClasses ().GetOrNull(classname); if (node != null && node.type != ClassesProcessor.ClassNode.Class_Root && node.type != ClassesProcessor.ClassNode.Class_Local && (node.access & ICodeConstants.Acc_Static ) == 0) { if (!(lstParams.Count == 0)) { Exprent enclosing = lstParams[0]; bool isQualifiedNew = false; if (enclosing.type == Exprent.Exprent_Var) { VarExprent varEnclosing = (VarExprent)enclosing; StructClass current_class = ((ClassesProcessor.ClassNode)DecompilerContext.GetProperty (DecompilerContext.Current_Class_Node)).classStruct; string this_classname = varEnclosing.GetProcessor().GetThisVars().GetOrNull(new VarVersionPair (varEnclosing)); if (!current_class.qualifiedName.Equals(this_classname)) { isQualifiedNew = true; } } else { isQualifiedNew = true; } if (isQualifiedNew) { return(enclosing.ToJava(indent, tracer).ToString()); } } } return(null); }
public virtual void Init() { DecompilerContext.SetProperty(DecompilerContext.Current_Class, classStruct); DecompilerContext.SetProperty(DecompilerContext.Current_Class_Wrapper, this); DecompilerContext.GetLogger().StartClass(classStruct.qualifiedName); int maxSec = System.Convert.ToInt32(DecompilerContext.GetProperty(IFernflowerPreferences .Max_Processing_Method).ToString()); bool testMode = DecompilerContext.GetOption(IFernflowerPreferences.Unit_Test_Mode ); foreach (StructMethod mt in classStruct.GetMethods()) { DecompilerContext.GetLogger().StartMethod(mt.GetName() + " " + mt.GetDescriptor() ); MethodDescriptor md = MethodDescriptor.ParseDescriptor(mt.GetDescriptor()); VarProcessor varProc = new VarProcessor(mt, md); DecompilerContext.StartMethod(varProc); VarNamesCollector vc = varProc.GetVarNamesCollector(); CounterContainer counter = DecompilerContext.GetCounterContainer(); RootStatement root = null; bool isError = false; try { if (mt.ContainsCode()) { if (maxSec == 0 || testMode) { root = MethodProcessorRunnable.CodeToJava(mt, md, varProc); } else { MethodProcessorRunnable mtProc = new MethodProcessorRunnable(mt, md, varProc, DecompilerContext .GetCurrentContext()); Thread mtThread = new Thread(o => mtProc.Run()) { Name = "Java decompiler" }; long stopAt = Runtime.CurrentTimeMillis() + maxSec * 1000L; mtThread.Start(); while (!mtProc.IsFinished()) { try { lock (mtProc.Lock) { Thread.Sleep(200); } } catch (Exception e) { KillThread(mtThread); throw; } if (Runtime.CurrentTimeMillis() >= stopAt) { string message = "Processing time limit exceeded for method " + mt.GetName() + ", execution interrupted."; DecompilerContext.GetLogger().WriteMessage(message, IFernflowerLogger.Severity.Error ); KillThread(mtThread); isError = true; break; } } if (!isError) { root = mtProc.GetResult(); } } } else { bool thisVar = !mt.HasModifier(ICodeConstants.Acc_Static); int paramCount = 0; if (thisVar) { Sharpen.Collections.Put(varProc.GetThisVars(), new VarVersionPair(0, 0), classStruct .qualifiedName); paramCount = 1; } paramCount += [email protected]; int varIndex = 0; for (int i = 0; i < paramCount; i++) { 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; } } } } catch (Exception t) { string message = "Method " + mt.GetName() + " " + mt.GetDescriptor() + " couldn't be decompiled."; DecompilerContext.GetLogger().WriteMessage(message, IFernflowerLogger.Severity.Warn , t); isError = true; } MethodWrapper methodWrapper = new MethodWrapper(root, varProc, mt, counter); methodWrapper.decompiledWithErrors = isError; methods.AddWithKey(methodWrapper, InterpreterUtil.MakeUniqueKey(mt.GetName(), mt. GetDescriptor())); if (!isError) { // rename vars so that no one has the same name as a field VarNamesCollector namesCollector = new VarNamesCollector(); classStruct.GetFields().ForEach((StructField f) => namesCollector.AddName(f.GetName ())); varProc.RefreshVarNames(namesCollector); // if debug information present and should be used if (DecompilerContext.GetOption(IFernflowerPreferences.Use_Debug_Var_Names)) { StructLocalVariableTableAttribute attr = mt.GetLocalVariableAttr(); if (attr != null) { // only param names here varProc.SetDebugVarNames(attr.GetMapParamNames()); // the rest is here methodWrapper.GetOrBuildGraph().IterateExprents((Exprent exprent) => { List <Exprent> lst = exprent.GetAllExprents(true); lst.Add(exprent); lst.Where(e => e.type == Exprent.Exprent_Var).ToList().ForEach((Exprent e) => { VarExprent varExprent = (VarExprent)e; string name = varExprent.GetDebugName(mt); if (name != null) { varProc.SetVarName(varExprent.GetVarVersionPair(), name); } } ); return(0); } ); } } } DecompilerContext.GetLogger().EndMethod(); } DecompilerContext.GetLogger().EndClass(); }
public override TextBuffer ToJava(int indent, BytecodeMappingTracer tracer) { TextBuffer buf = new TextBuffer(); if (isStatic__) { ClassesProcessor.ClassNode node = (ClassesProcessor.ClassNode)DecompilerContext.GetProperty (DecompilerContext.Current_Class_Node); if (node == null || !classname.Equals(node.classStruct.qualifiedName) || IsAmbiguous ()) { buf.Append(DecompilerContext.GetImportCollector().GetShortNameInClassContext(ExprProcessor .BuildJavaClassName(classname))); buf.Append("."); } } else { string super_qualifier = null; if (instance != null && instance.type == Exprent.Exprent_Var) { VarExprent instVar = (VarExprent)instance; VarVersionPair pair = new VarVersionPair(instVar); MethodWrapper currentMethod = (MethodWrapper)DecompilerContext.GetProperty(DecompilerContext .Current_Method_Wrapper); if (currentMethod != null) { // FIXME: remove string this_classname = currentMethod.varproc.GetThisVars().GetOrNull(pair); if (this_classname != null) { if (!classname.Equals(this_classname)) { // TODO: direct comparison to the super class? super_qualifier = this_classname; } } } } if (super_qualifier != null) { TextUtil.WriteQualifiedSuper(buf, super_qualifier); } else { TextBuffer buff = new TextBuffer(); bool casted = ExprProcessor.GetCastedExprent(instance, new VarType(ICodeConstants .Type_Object, 0, classname), buff, indent, true, tracer); string res = buff.ToString(); if (casted || instance.GetPrecedence() > GetPrecedence()) { res = "(" + res + ")"; } buf.Append(res); } if (buf.ToString().Equals(VarExprent.Var_Nameless_Enclosure)) { // FIXME: workaround for field access of an anonymous enclosing class. Find a better way. buf.SetLength(0); } else { buf.Append("."); } } buf.Append(name); tracer.AddMapping(bytecode); return(buf); }
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); }
public override TextBuffer ToJava(int indent, BytecodeMappingTracer tracer) { VarType leftType = left.GetExprType(); VarType rightType = right.GetExprType(); bool fieldInClassInit = false; bool hiddenField = false; if (left.type == Exprent.Exprent_Field) { // first assignment to a final field. Field name without "this" in front of it FieldExprent field = (FieldExprent)left; ClassesProcessor.ClassNode node = ((ClassesProcessor.ClassNode)DecompilerContext. GetProperty(DecompilerContext.Current_Class_Node)); if (node != null) { StructField fd = node.classStruct.GetField(field.GetName(), field.GetDescriptor() .descriptorString); if (fd != null) { if (field.IsStatic() && fd.HasModifier(ICodeConstants.Acc_Final)) { fieldInClassInit = true; } if (node.GetWrapper() != null && node.GetWrapper().GetHiddenMembers().Contains(InterpreterUtil .MakeUniqueKey(fd.GetName(), fd.GetDescriptor()))) { hiddenField = true; } } } } if (hiddenField) { return(new TextBuffer()); } TextBuffer buffer = new TextBuffer(); if (fieldInClassInit) { buffer.Append(((FieldExprent)left).GetName()); } else { buffer.Append(left.ToJava(indent, tracer)); } if (right.type == Exprent_Const) { ((ConstExprent)right).AdjustConstType(leftType); } TextBuffer res = right.ToJava(indent, tracer); if (condType == Condition_None && !leftType.IsSuperset(rightType) && (rightType.Equals (VarType.Vartype_Object) || leftType.type != ICodeConstants.Type_Object)) { if (right.GetPrecedence() >= FunctionExprent.GetPrecedence(FunctionExprent.Function_Cast )) { res.Enclose("(", ")"); } res.Prepend("(" + ExprProcessor.GetCastTypeName(leftType) + ")"); } buffer.Append(condType == Condition_None ? " = " : Operators[condType]).Append(res ); tracer.AddMapping(bytecode); return(buffer); }
public override TextBuffer ToJava(int indent, BytecodeMappingTracer tracer) { TextBuffer buf = new TextBuffer(); string super_qualifier = null; bool isInstanceThis = false; tracer.AddMapping(bytecode); if (instance is InvocationExprent) { ((InvocationExprent)instance).MarkUsingBoxingResult(); } if (isStatic__) { if (IsBoxingCall() && canIgnoreBoxing) { // process general "boxing" calls, e.g. 'Object[] data = { true }' or 'Byte b = 123' // here 'byte' and 'short' values do not need an explicit narrowing type cast ExprProcessor.GetCastedExprent(lstParameters[0], descriptor.@params[0], buf, indent , false, false, false, false, tracer); return(buf); } ClassesProcessor.ClassNode node = (ClassesProcessor.ClassNode)DecompilerContext.GetProperty (DecompilerContext.Current_Class_Node); if (node == null || !classname.Equals(node.classStruct.qualifiedName)) { buf.Append(DecompilerContext.GetImportCollector().GetShortNameInClassContext(ExprProcessor .BuildJavaClassName(classname))); } } else { if (instance != null && instance.type == Exprent.Exprent_Var) { VarExprent instVar = (VarExprent)instance; VarVersionPair varPair = new VarVersionPair(instVar); VarProcessor varProc = instVar.GetProcessor(); if (varProc == null) { MethodWrapper currentMethod = (MethodWrapper)DecompilerContext.GetProperty(DecompilerContext .Current_Method_Wrapper); if (currentMethod != null) { varProc = currentMethod.varproc; } } string this_classname = null; if (varProc != null) { this_classname = varProc.GetThisVars().GetOrNull(varPair); } if (this_classname != null) { isInstanceThis = true; if (invocationTyp == Invoke_Special) { if (!classname.Equals(this_classname)) { // TODO: direct comparison to the super class? StructClass cl = DecompilerContext.GetStructContext().GetClass(classname); bool isInterface = cl != null && cl.HasModifier(ICodeConstants.Acc_Interface); super_qualifier = !isInterface ? this_classname : classname; } } } } if (functype == Typ_General) { if (super_qualifier != null) { TextUtil.WriteQualifiedSuper(buf, super_qualifier); } else if (instance != null) { TextBuffer res = instance.ToJava(indent, tracer); if (IsUnboxingCall()) { // we don't print the unboxing call - no need to bother with the instance wrapping / casting buf.Append(res); return(buf); } VarType rightType = instance.GetExprType(); VarType leftType = new VarType(ICodeConstants.Type_Object, 0, classname); if (rightType.Equals(VarType.Vartype_Object) && !leftType.Equals(rightType)) { buf.Append("((").Append(ExprProcessor.GetCastTypeName(leftType)).Append(")"); if (instance.GetPrecedence() >= FunctionExprent.GetPrecedence(FunctionExprent.Function_Cast )) { res.Enclose("(", ")"); } buf.Append(res).Append(")"); } else if (instance.GetPrecedence() > GetPrecedence()) { buf.Append("(").Append(res).Append(")"); } else { buf.Append(res); } } } } switch (functype) { case Typ_General: { if (VarExprent.Var_Nameless_Enclosure.Equals(buf.ToString())) { buf = new TextBuffer(); } if (buf.Length() > 0) { buf.Append("."); } buf.Append(name); if (invocationTyp == Invoke_Dynamic) { buf.Append("<invokedynamic>"); } buf.Append("("); break; } case Typ_Clinit: { throw new Exception("Explicit invocation of " + ICodeConstants.Clinit_Name); } case Typ_Init: { if (super_qualifier != null) { buf.Append("super("); } else if (isInstanceThis) { buf.Append("this("); } else if (instance != null) { buf.Append(instance.ToJava(indent, tracer)).Append(".<init>("); } else { throw new Exception("Unrecognized invocation of " + ICodeConstants.Init_Name); } break; } } List <VarVersionPair> mask = null; bool isEnum = false; if (functype == Typ_Init) { ClassesProcessor.ClassNode newNode = DecompilerContext.GetClassProcessor().GetMapRootClasses ().GetOrNull(classname); if (newNode != null) { mask = ExprUtil.GetSyntheticParametersMask(newNode, stringDescriptor, lstParameters .Count); isEnum = newNode.classStruct.HasModifier(ICodeConstants.Acc_Enum) && DecompilerContext .GetOption(IFernflowerPreferences.Decompile_Enum); } } BitSet setAmbiguousParameters = GetAmbiguousParameters(); // omit 'new Type[] {}' for the last parameter of a vararg method call if (lstParameters.Count == [email protected] && IsVarArgCall()) { Exprent lastParam = lstParameters[lstParameters.Count - 1]; if (lastParam.type == Exprent_New && lastParam.GetExprType().arrayDim >= 1) { ((NewExprent)lastParam).SetVarArgParam(true); } } bool firstParameter = true; int start = isEnum ? 2 : 0; for (int i = start; i < lstParameters.Count; i++) { if (mask == null || mask[i] == null) { TextBuffer buff = new TextBuffer(); bool ambiguous = setAmbiguousParameters.Get(i); // 'byte' and 'short' literals need an explicit narrowing type cast when used as a parameter ExprProcessor.GetCastedExprent(lstParameters[i], descriptor.@params[i], buff, indent , true, ambiguous, true, true, tracer); // the last "new Object[0]" in the vararg call is not printed if (buff.Length() > 0) { if (!firstParameter) { buf.Append(", "); } buf.Append(buff); } firstParameter = false; } } buf.Append(')'); return(buf); }