示例#1
0
        public override TextBuffer ToJava(int indent, BytecodeMappingTracer tracer)
        {
            TextBuffer buf       = new TextBuffer();
            bool       islabeled = IsLabeled();

            buf.Append(ExprProcessor.ListToJava(varDefinitions, indent, tracer));
            if (islabeled)
            {
                buf.AppendIndent(indent++).Append("label").Append(this.id.ToString()).Append(": {"
                                                                                             ).AppendLineSeparator();
                tracer.IncrementCurrentSourceLine();
            }
            bool notempty = false;

            for (int i = 0; i < stats.Count; i++)
            {
                Statement st = stats[i];
                if (i > 0 && notempty)
                {
                    buf.AppendLineSeparator();
                    tracer.IncrementCurrentSourceLine();
                }
                TextBuffer str = ExprProcessor.JmpWrapper(st, indent, false, tracer);
                buf.Append(str);
                notempty = !str.ContainsOnlyWhitespaces();
            }
            if (islabeled)
            {
                buf.AppendIndent(indent - 1).Append("}").AppendLineSeparator();
                tracer.IncrementCurrentSourceLine();
            }
            return(buf);
        }
示例#2
0
        public override TextBuffer ToJava(int indent, BytecodeMappingTracer tracer)
        {
            SwitchHelper.Simplify(this);
            TextBuffer buf = new TextBuffer();

            buf.Append(ExprProcessor.ListToJava(varDefinitions, indent, tracer));
            buf.Append(first.ToJava(indent, tracer));
            if (IsLabeled())
            {
                buf.AppendIndent(indent).Append("label").Append(this.id.ToString()).Append(":").AppendLineSeparator
                    ();
                tracer.IncrementCurrentSourceLine();
            }
            buf.AppendIndent(indent).Append(headexprent[0].ToJava(indent, tracer)).Append(" {"
                                                                                          ).AppendLineSeparator();
            tracer.IncrementCurrentSourceLine();
            VarType switch_type = headexprent[0].GetExprType();

            for (int i = 0; i < caseStatements.Count; i++)
            {
                Statement       stat   = caseStatements[i];
                List <StatEdge> edges  = caseEdges[i];
                List <Exprent>  values = caseValues[i];
                for (int j = 0; j < edges.Count; j++)
                {
                    if (edges[j] == default_edge)
                    {
                        buf.AppendIndent(indent).Append("default:").AppendLineSeparator();
                    }
                    else
                    {
                        buf.AppendIndent(indent).Append("case ");
                        Exprent value = values[j];
                        if (value is ConstExprent)
                        {
                            value = value.Copy();
                            ((ConstExprent)value).SetConstType(switch_type);
                        }
                        if (value is FieldExprent && ((FieldExprent)value).IsStatic())
                        {
                            // enum values
                            buf.Append(((FieldExprent)value).GetName());
                        }
                        else
                        {
                            buf.Append(value.ToJava(indent, tracer));
                        }
                        buf.Append(":").AppendLineSeparator();
                    }
                    tracer.IncrementCurrentSourceLine();
                }
                buf.Append(ExprProcessor.JmpWrapper(stat, indent + 1, false, tracer));
            }
            buf.AppendIndent(indent).Append("}").AppendLineSeparator();
            tracer.IncrementCurrentSourceLine();
            return(buf);
        }
示例#3
0
        public override TextBuffer ToJava(int indent, BytecodeMappingTracer tracer)
        {
            TextBuffer buf = new TextBuffer();

            buf.Append(ExprProcessor.ListToJava(varDefinitions, indent, tracer));
            if (IsLabeled())
            {
                buf.AppendIndent(indent).Append("label").Append(this.id.ToString()).Append(":").AppendLineSeparator
                    ();
                tracer.IncrementCurrentSourceLine();
            }
            buf.AppendIndent(indent).Append("try {").AppendLineSeparator();
            tracer.IncrementCurrentSourceLine();
            buf.Append(ExprProcessor.JmpWrapper(first, indent + 1, true, tracer));
            buf.AppendIndent(indent).Append("}");
            for (int i = 1; i < stats.Count; i++)
            {
                Statement stat = stats[i];
                // map first instruction storing the exception to the catch statement
                BasicBlock block = stat.GetBasichead().GetBlock();
                if (!block.GetSeq().IsEmpty() && block.GetInstruction(0).opcode == ICodeConstants
                    .opc_astore)
                {
                    int offset = block.GetOldOffset(0);
                    if (offset > -1)
                    {
                        tracer.AddMapping(offset);
                    }
                }
                buf.Append(" catch (");
                List <string> exception_types = exctstrings[i - 1];
                if (exception_types.Count > 1)
                {
                    // multi-catch, Java 7 style
                    for (int exc_index = 1; exc_index < exception_types.Count; ++exc_index)
                    {
                        VarType exc_type = new VarType(ICodeConstants.Type_Object, 0, exception_types[exc_index
                                                       ]);
                        string exc_type_name = ExprProcessor.GetCastTypeName(exc_type);
                        buf.Append(exc_type_name).Append(" | ");
                    }
                }
                buf.Append(vars[i - 1].ToJava(indent, tracer));
                buf.Append(") {").AppendLineSeparator();
                tracer.IncrementCurrentSourceLine();
                buf.Append(ExprProcessor.JmpWrapper(stat, indent + 1, false, tracer)).AppendIndent
                    (indent).Append("}");
            }
            buf.AppendLineSeparator();
            tracer.IncrementCurrentSourceLine();
            return(buf);
        }
示例#4
0
        public override TextBuffer ToJava(int indent, BytecodeMappingTracer tracer)
        {
            TextBuffer buffer = new TextBuffer();

            tracer.AddMapping(bytecode);
            if (classDef)
            {
                ClassesProcessor.ClassNode child = DecompilerContext.GetClassProcessor().GetMapRootClasses
                                                       ().GetOrNull(varType.value);
                new ClassWriter().ClassToJava(child, buffer, indent, tracer);
                tracer.IncrementCurrentSourceLine(buffer.CountLines());
            }
            else
            {
                VarVersionPair varVersion = GetVarVersionPair();
                string         name       = null;
                if (processor != null)
                {
                    name = processor.GetVarName(varVersion);
                }
                if (definition)
                {
                    if (processor != null && processor.GetVarFinal(varVersion) == VarTypeProcessor.Var_Explicit_Final)
                    {
                        buffer.Append("final ");
                    }
                    AppendDefinitionType(buffer);
                    buffer.Append(" ");
                }
                buffer.Append(name == null ? ("var" + index + (this.version == 0 ? string.Empty :
                                                               "_" + this.version)) : name);
            }
            return(buffer);
        }
        // *****************************************************************************
        // public methods
        // *****************************************************************************
        public override TextBuffer ToJava(int indent, BytecodeMappingTracer tracer)
        {
            TextBuffer buf = new TextBuffer();

            buf.Append(ExprProcessor.ListToJava(varDefinitions, indent, tracer));
            buf.Append(first.ToJava(indent, tracer));
            if (IsLabeled())
            {
                buf.AppendIndent(indent).Append("label").Append(this.id.ToString()).Append(":").AppendLineSeparator
                    ();
                tracer.IncrementCurrentSourceLine();
            }
            buf.AppendIndent(indent).Append(headexprent[0].ToJava(indent, tracer)).Append(" {"
                                                                                          ).AppendLineSeparator();
            tracer.IncrementCurrentSourceLine();
            buf.Append(ExprProcessor.JmpWrapper(body, indent + 1, true, tracer));
            buf.AppendIndent(indent).Append("}").AppendLineSeparator();
            MapMonitorExitInstr(tracer);
            tracer.IncrementCurrentSourceLine();
            return(buf);
        }
示例#6
0
        public override TextBuffer ToJava(int indent, BytecodeMappingTracer tracer)
        {
            string     new_line_separator = DecompilerContext.GetNewLineSeparator();
            TextBuffer buf = new TextBuffer();

            buf.Append(ExprProcessor.ListToJava(varDefinitions, indent, tracer));
            bool labeled = IsLabeled();

            if (labeled)
            {
                buf.AppendIndent(indent).Append("label").Append(this.id.ToString()).Append(":").AppendLineSeparator
                    ();
                tracer.IncrementCurrentSourceLine();
            }
            List <StatEdge> lstSuccs = first.GetSuccessorEdges(Statedge_Direct_All);

            if (first.type == Type_Trycatch && (first.varDefinitions.Count == 0) && isFinally__ &&
                !labeled && !first.IsLabeled() && ((lstSuccs.Count == 0) || !lstSuccs[0].@explicit
                                                   ))
            {
                TextBuffer content = ExprProcessor.JmpWrapper(first, indent, true, tracer);
                content.SetLength(content.Length() - new_line_separator.Length);
                tracer.IncrementCurrentSourceLine(-1);
                buf.Append(content);
            }
            else
            {
                buf.AppendIndent(indent).Append("try {").AppendLineSeparator();
                tracer.IncrementCurrentSourceLine();
                buf.Append(ExprProcessor.JmpWrapper(first, indent + 1, true, tracer));
                buf.AppendIndent(indent).Append("}");
            }
            buf.Append(isFinally__ ? " finally" : " catch (" + vars[0].ToJava(indent, tracer)
                       + ")").Append(" {").AppendLineSeparator();
            tracer.IncrementCurrentSourceLine();
            if (monitor != null)
            {
                buf.AppendIndent(indent + 1).Append("if (").Append(monitor.ToJava(indent, tracer)
                                                                   ).Append(") {").AppendLineSeparator();
                tracer.IncrementCurrentSourceLine();
            }
            buf.Append(ExprProcessor.JmpWrapper(handler, indent + 1 + (monitor != null ? 1 :
                                                                       0), true, tracer));
            if (monitor != null)
            {
                buf.AppendIndent(indent + 1).Append("}").AppendLineSeparator();
                tracer.IncrementCurrentSourceLine();
            }
            buf.AppendIndent(indent).Append("}").AppendLineSeparator();
            tracer.IncrementCurrentSourceLine();
            return(buf);
        }
示例#7
0
        public override TextBuffer ToJava(int indent, BytecodeMappingTracer tracer)
        {
            TextBuffer buf = new TextBuffer();

            buf.Append(ExprProcessor.ListToJava(varDefinitions, indent, tracer));
            buf.Append(first.ToJava(indent, tracer));
            if (IsLabeled())
            {
                buf.AppendIndent(indent).Append("label").Append(this.id.ToString()).Append(":").AppendLineSeparator
                    ();
                tracer.IncrementCurrentSourceLine();
            }
            buf.AppendIndent(indent).Append(headexprent[0].ToJava(indent, tracer)).Append(" {"
                                                                                          ).AppendLineSeparator();
            tracer.IncrementCurrentSourceLine();
            if (ifstat == null)
            {
                bool semicolon = false;
                if (ifedge.@explicit)
                {
                    semicolon = true;
                    if (ifedge.GetType() == StatEdge.Type_Break)
                    {
                        // break
                        buf.AppendIndent(indent + 1).Append("break");
                    }
                    else
                    {
                        // continue
                        buf.AppendIndent(indent + 1).Append("continue");
                    }
                    if (ifedge.labeled)
                    {
                        buf.Append(" label").Append(ifedge.closure.id.ToString());
                    }
                }
                if (semicolon)
                {
                    buf.Append(";").AppendLineSeparator();
                    tracer.IncrementCurrentSourceLine();
                }
            }
            else
            {
                buf.Append(ExprProcessor.JmpWrapper(ifstat, indent + 1, true, tracer));
            }
            bool elseif = false;

            if (elsestat != null)
            {
                if (elsestat.type == Statement.Type_If && (elsestat.varDefinitions.Count == 0) &&
                    (elsestat.GetFirst().GetExprents().Count == 0) && !elsestat.IsLabeled() && ((elsestat
                                                                                                 .GetSuccessorEdges(Statedge_Direct_All).Count == 0) || !elsestat.GetSuccessorEdges
                                                                                                    (Statedge_Direct_All)[0].@explicit))
                {
                    // else if
                    buf.AppendIndent(indent).Append("} else ");
                    TextBuffer content = ExprProcessor.JmpWrapper(elsestat, indent, false, tracer);
                    content.SetStart(TextUtil.GetIndentString(indent).Length);
                    buf.Append(content);
                    elseif = true;
                }
                else
                {
                    BytecodeMappingTracer else_tracer = new BytecodeMappingTracer(tracer.GetCurrentSourceLine
                                                                                      () + 1);
                    TextBuffer content = ExprProcessor.JmpWrapper(elsestat, indent + 1, false, else_tracer
                                                                  );
                    if (content.Length() > 0)
                    {
                        buf.AppendIndent(indent).Append("} else {").AppendLineSeparator();
                        tracer.SetCurrentSourceLine(else_tracer.GetCurrentSourceLine());
                        tracer.AddTracer(else_tracer);
                        buf.Append(content);
                    }
                }
            }
            if (!elseif)
            {
                buf.AppendIndent(indent).Append("}").AppendLineSeparator();
                tracer.IncrementCurrentSourceLine();
            }
            return(buf);
        }
示例#8
0
        // precedence of new
        public override TextBuffer ToJava(int indent, BytecodeMappingTracer tracer)
        {
            TextBuffer buf = new TextBuffer();

            if (anonymous)
            {
                ClassesProcessor.ClassNode child = DecompilerContext.GetClassProcessor().GetMapRootClasses
                                                       ().GetOrNull(newType.value);
                // IDEA-204310 - avoid backtracking later on for lambdas (causes spurious imports)
                if (!enumConst && (!lambda || DecompilerContext.GetOption(IFernflowerPreferences
                                                                          .Lambda_To_Anonymous_Class)))
                {
                    string enclosing = null;
                    if (!lambda && constructor != null)
                    {
                        enclosing = GetQualifiedNewInstance(child.anonymousClassType.value, constructor.GetLstParameters
                                                                (), indent, tracer);
                        if (enclosing != null)
                        {
                            buf.Append(enclosing).Append('.');
                        }
                    }
                    buf.Append("new ");
                    string typename = ExprProcessor.GetCastTypeName(child.anonymousClassType);
                    if (enclosing != null)
                    {
                        ClassesProcessor.ClassNode anonymousNode = DecompilerContext.GetClassProcessor().
                                                                   GetMapRootClasses().GetOrNull(child.anonymousClassType.value);
                        if (anonymousNode != null)
                        {
                            typename = anonymousNode.simpleName;
                        }
                        else
                        {
                            typename = Sharpen.Runtime.Substring(typename, typename.LastIndexOf('.') + 1);
                        }
                    }
                    GenericClassDescriptor descriptor = ClassWriter.GetGenericClassDescriptor(child.classStruct
                                                                                              );
                    if (descriptor != null)
                    {
                        if ((descriptor.superinterfaces.Count == 0))
                        {
                            buf.Append(GenericMain.GetGenericCastTypeName(descriptor.superclass));
                        }
                        else
                        {
                            if (descriptor.superinterfaces.Count > 1 && !lambda)
                            {
                                DecompilerContext.GetLogger().WriteMessage("Inconsistent anonymous class signature: "
                                                                           + child.classStruct.qualifiedName, IFernflowerLogger.Severity.Warn);
                            }
                            buf.Append(GenericMain.GetGenericCastTypeName(descriptor.superinterfaces[0]));
                        }
                    }
                    else
                    {
                        buf.Append(typename);
                    }
                }
                buf.Append('(');
                if (!lambda && constructor != null)
                {
                    List <Exprent>        parameters = constructor.GetLstParameters();
                    List <VarVersionPair> mask       = child.GetWrapper().GetMethodWrapper(ICodeConstants.Init_Name
                                                                                           , constructor.GetStringDescriptor()).synthParameters;
                    if (mask == null)
                    {
                        InvocationExprent superCall = child.superInvocation;
                        mask = ExprUtil.GetSyntheticParametersMask(superCall.GetClassname(), superCall.GetStringDescriptor
                                                                       (), parameters.Count);
                    }
                    int  start      = enumConst ? 2 : 0;
                    bool firstParam = true;
                    for (int i = start; i < parameters.Count; i++)
                    {
                        if (mask == null || mask[i] == null)
                        {
                            if (!firstParam)
                            {
                                buf.Append(", ");
                            }
                            ExprProcessor.GetCastedExprent(parameters[i], constructor.GetDescriptor().@params
                                                           [i], buf, indent, true, tracer);
                            firstParam = false;
                        }
                    }
                }
                buf.Append(')');
                if (enumConst && buf.Length() == 2)
                {
                    buf.SetLength(0);
                }
                if (lambda)
                {
                    if (!DecompilerContext.GetOption(IFernflowerPreferences.Lambda_To_Anonymous_Class
                                                     ))
                    {
                        buf.SetLength(0);
                    }
                    // remove the usual 'new <class>()', it will be replaced with lambda style '() ->'
                    Exprent    methodObject = constructor == null ? null : constructor.GetInstance();
                    TextBuffer clsBuf       = new TextBuffer();
                    new ClassWriter().ClassLambdaToJava(child, clsBuf, methodObject, indent, tracer);
                    buf.Append(clsBuf);
                    tracer.IncrementCurrentSourceLine(clsBuf.CountLines());
                }
                else
                {
                    TextBuffer clsBuf = new TextBuffer();
                    new ClassWriter().ClassToJava(child, clsBuf, indent, tracer);
                    buf.Append(clsBuf);
                    tracer.IncrementCurrentSourceLine(clsBuf.CountLines());
                }
            }
            else if (directArrayInit)
            {
                VarType leftType = newType.DecreaseArrayDim();
                buf.Append('{');
                for (int i = 0; i < lstArrayElements.Count; i++)
                {
                    if (i > 0)
                    {
                        buf.Append(", ");
                    }
                    ExprProcessor.GetCastedExprent(lstArrayElements[i], leftType, buf, indent, false,
                                                   tracer);
                }
                buf.Append('}');
            }
            else if (newType.arrayDim == 0)
            {
                if (!enumConst)
                {
                    string enclosing = null;
                    if (constructor != null)
                    {
                        enclosing = GetQualifiedNewInstance(newType.value, constructor.GetLstParameters()
                                                            , indent, tracer);
                        if (enclosing != null)
                        {
                            buf.Append(enclosing).Append('.');
                        }
                    }
                    buf.Append("new ");
                    string typename = ExprProcessor.GetTypeName(newType);
                    if (enclosing != null)
                    {
                        ClassesProcessor.ClassNode newNode = DecompilerContext.GetClassProcessor().GetMapRootClasses
                                                                 ().GetOrNull(newType.value);
                        if (newNode != null)
                        {
                            typename = newNode.simpleName;
                        }
                        else
                        {
                            typename = Sharpen.Runtime.Substring(typename, typename.LastIndexOf('.') + 1);
                        }
                    }
                    buf.Append(typename);
                }
                if (constructor != null)
                {
                    List <Exprent>        parameters = constructor.GetLstParameters();
                    List <VarVersionPair> mask       = ExprUtil.GetSyntheticParametersMask(constructor.GetClassname
                                                                                               (), constructor.GetStringDescriptor(), parameters.Count);
                    int start = enumConst ? 2 : 0;
                    if (!enumConst || start < parameters.Count)
                    {
                        buf.Append('(');
                        bool firstParam = true;
                        for (int i = start; i < parameters.Count; i++)
                        {
                            if (mask == null || mask[i] == null)
                            {
                                Exprent expr     = parameters[i];
                                VarType leftType = constructor.GetDescriptor().@params[i];
                                if (i == parameters.Count - 1 && expr.GetExprType() == VarType.Vartype_Null && ProbablySyntheticParameter
                                        (leftType.value))
                                {
                                    break;
                                }
                                // skip last parameter of synthetic constructor call
                                if (!firstParam)
                                {
                                    buf.Append(", ");
                                }
                                ExprProcessor.GetCastedExprent(expr, leftType, buf, indent, true, false, true, true
                                                               , tracer);
                                firstParam = false;
                            }
                        }
                        buf.Append(')');
                    }
                }
            }
            else if (isVarArgParam)
            {
                // just print the array elements
                VarType leftType = newType.DecreaseArrayDim();
                for (int i = 0; i < lstArrayElements.Count; i++)
                {
                    if (i > 0)
                    {
                        buf.Append(", ");
                    }
                    // new String[][]{{"abc"}, {"DEF"}} => new String[]{"abc"}, new String[]{"DEF"}
                    Exprent element = lstArrayElements[i];
                    if (element.type == Exprent_New)
                    {
                        ((NewExprent)element).SetDirectArrayInit(false);
                    }
                    ExprProcessor.GetCastedExprent(element, leftType, buf, indent, false, tracer);
                }
                // if there is just one element of Object[] type it needs to be casted to resolve ambiguity
                if (lstArrayElements.Count == 1)
                {
                    VarType elementType = lstArrayElements[0].GetExprType();
                    if (elementType.type == ICodeConstants.Type_Object && elementType.value.Equals("java/lang/Object"
                                                                                                   ) && elementType.arrayDim >= 1)
                    {
                        buf.Prepend("(Object)");
                    }
                }
            }
            else
            {
                buf.Append("new ").Append(ExprProcessor.GetTypeName(newType));
                if ((lstArrayElements.Count == 0))
                {
                    for (int i = 0; i < newType.arrayDim; i++)
                    {
                        buf.Append('[');
                        if (i < lstDims.Count)
                        {
                            buf.Append(lstDims[i].ToJava(indent, tracer));
                        }
                        buf.Append(']');
                    }
                }
                else
                {
                    for (int i = 0; i < newType.arrayDim; i++)
                    {
                        buf.Append("[]");
                    }
                    VarType leftType = newType.DecreaseArrayDim();
                    buf.Append('{');
                    for (int i = 0; i < lstArrayElements.Count; i++)
                    {
                        if (i > 0)
                        {
                            buf.Append(", ");
                        }
                        ExprProcessor.GetCastedExprent(lstArrayElements[i], leftType, buf, indent, false,
                                                       tracer);
                    }
                    buf.Append('}');
                }
            }
            return(buf);
        }
示例#9
0
        public override TextBuffer ToJava(int indent, BytecodeMappingTracer tracer)
        {
            TextBuffer buf = new TextBuffer();

            buf.Append(ExprProcessor.ListToJava(varDefinitions, indent, tracer));
            if (IsLabeled())
            {
                buf.AppendIndent(indent).Append("label").Append(this.id.ToString()).Append(":").AppendLineSeparator
                    ();
                tracer.IncrementCurrentSourceLine();
            }
            switch (looptype)
            {
            case Loop_Do:
            {
                buf.AppendIndent(indent).Append("while(true) {").AppendLineSeparator();
                tracer.IncrementCurrentSourceLine();
                buf.Append(ExprProcessor.JmpWrapper(first, indent + 1, false, tracer));
                buf.AppendIndent(indent).Append("}").AppendLineSeparator();
                tracer.IncrementCurrentSourceLine();
                break;
            }

            case Loop_Dowhile:
            {
                buf.AppendIndent(indent).Append("do {").AppendLineSeparator();
                tracer.IncrementCurrentSourceLine();
                buf.Append(ExprProcessor.JmpWrapper(first, indent + 1, false, tracer));
                buf.AppendIndent(indent).Append("} while(").Append(conditionExprent[0].ToJava(indent
                                                                                              , tracer)).Append(");").AppendLineSeparator();
                tracer.IncrementCurrentSourceLine();
                break;
            }

            case Loop_While:
            {
                buf.AppendIndent(indent).Append("while(").Append(conditionExprent[0].ToJava(indent
                                                                                            , tracer)).Append(") {").AppendLineSeparator();
                tracer.IncrementCurrentSourceLine();
                buf.Append(ExprProcessor.JmpWrapper(first, indent + 1, false, tracer));
                buf.AppendIndent(indent).Append("}").AppendLineSeparator();
                tracer.IncrementCurrentSourceLine();
                break;
            }

            case Loop_For:
            {
                buf.AppendIndent(indent).Append("for(");
                if (initExprent[0] != null)
                {
                    buf.Append(initExprent[0].ToJava(indent, tracer));
                }
                buf.Append("; ").Append(conditionExprent[0].ToJava(indent, tracer)).Append("; ").
                Append(incExprent[0].ToJava(indent, tracer)).Append(") {").AppendLineSeparator();
                tracer.IncrementCurrentSourceLine();
                buf.Append(ExprProcessor.JmpWrapper(first, indent + 1, false, tracer));
                buf.AppendIndent(indent).Append("}").AppendLineSeparator();
                tracer.IncrementCurrentSourceLine();
                break;
            }
            }
            return(buf);
        }