Example #1
0
        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);
        }
Example #2
0
 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");
 }
Example #3
0
 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()));
 }
Example #4
0
        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());
            }
        }
Example #5
0
        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());
        }
Example #6
0
 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 "));
     }
 }
Example #7
0
        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);
        }
Example #8
0
 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);
 }
Example #9
0
        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();
        }
Example #10
0
        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);
        }
Example #12
0
        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);
        }
Example #13
0
        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);
        }