コード例 #1
0
 /// <exception cref="System.IO.IOException"/>
 public virtual void WriteClass(StructClass cl, TextBuffer buffer)
 {
     ClassesProcessor.ClassNode root = mapRootClasses.GetOrNull(cl.qualifiedName);
     if (root.type != ClassesProcessor.ClassNode.Class_Root)
     {
         return;
     }
     DecompilerContext.GetLogger().StartReadingClass(cl.qualifiedName);
     try
     {
         ImportCollector importCollector = new ImportCollector(root);
         DecompilerContext.StartClass(importCollector);
         new LambdaProcessor().ProcessClass(root);
         // add simple class names to implicit import
         AddClassnameToImport(root, importCollector);
         // build wrappers for all nested classes (that's where actual processing takes place)
         InitWrappers(root);
         new NestedClassProcessor().ProcessClass(root, root);
         new NestedMemberAccess().PropagateMemberAccess(root);
         TextBuffer classBuffer = new TextBuffer(Average_Class_Size);
         new ClassWriter().ClassToJava(root, classBuffer, 0, null);
         int index = cl.qualifiedName.LastIndexOf("/");
         if (index >= 0)
         {
             string packageName = Sharpen.Runtime.Substring(cl.qualifiedName, 0, index).Replace
                                      ('/', '.');
             buffer.Append("package ");
             buffer.Append(packageName);
             buffer.Append(";");
             buffer.AppendLineSeparator();
             buffer.AppendLineSeparator();
         }
         int import_lines_written = importCollector.WriteImports(buffer);
         if (import_lines_written > 0)
         {
             buffer.AppendLineSeparator();
         }
         int offsetLines = buffer.CountLines();
         buffer.Append(classBuffer);
         if (DecompilerContext.GetOption(IFernflowerPreferences.Bytecode_Source_Mapping))
         {
             BytecodeSourceMapper mapper = DecompilerContext.GetBytecodeSourceMapper();
             mapper.AddTotalOffset(offsetLines);
             if (DecompilerContext.GetOption(IFernflowerPreferences.Dump_Original_Lines))
             {
                 buffer.DumpOriginalLineNumbers(mapper.GetOriginalLinesMapping());
             }
             if (DecompilerContext.GetOption(IFernflowerPreferences.Unit_Test_Mode))
             {
                 buffer.AppendLineSeparator();
                 mapper.DumpMapping(buffer, true);
             }
         }
     }
     finally
     {
         DestroyWrappers(root);
         DecompilerContext.GetLogger().EndReadingClass();
     }
 }
コード例 #2
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);
        }
コード例 #3
0
        public virtual void DumpMapping(TextBuffer buffer, bool offsetsToHex)
        {
            if ((mapping.Count == 0) && (linesMapping.Count == 0))
            {
                return;
            }
            string lineSeparator = DecompilerContext.GetNewLineSeparator();

            foreach (KeyValuePair <string, Dictionary <string, Dictionary <int, int> > > class_entry
                     in mapping)
            {
                Dictionary <string, Dictionary <int, int> > class_mapping = class_entry.Value;
                buffer.Append("class '" + class_entry.Key + "' {" + lineSeparator);
                bool is_first_method = true;
                foreach (KeyValuePair <string, Dictionary <int, int> > method_entry in class_mapping)
                {
                    Dictionary <int, int> method_mapping = method_entry.Value;
                    if (!is_first_method)
                    {
                        buffer.AppendLineSeparator();
                    }
                    buffer.AppendIndent(1).Append("method '" + method_entry.Key + "' {" + lineSeparator
                                                  );
                    List <int> lstBytecodeOffsets = new List <int>(method_mapping.Keys);
                    lstBytecodeOffsets.Sort();
                    foreach (int offset in lstBytecodeOffsets)
                    {
                        int?   line      = method_mapping.GetOrNullable(offset);
                        string strOffset = offsetsToHex ? Sharpen.Runtime.ToHexString(offset) : line.ToString();
                        buffer.AppendIndent(2).Append(strOffset).AppendIndent(2).Append((line.Value + offset_total
                                                                                         ) + lineSeparator);
                    }
                    buffer.AppendIndent(1).Append("}").AppendLineSeparator();
                    is_first_method = false;
                }
                buffer.Append("}").AppendLineSeparator().AppendLineSeparator();
            }
            // lines mapping
            buffer.Append("Lines mapping:").AppendLineSeparator();
            IDictionary <int, int> sorted = new SortedDictionary <int, int>(linesMapping);

            foreach (KeyValuePair <int, int> entry in sorted)
            {
                buffer.Append(entry.Key).Append(" <-> ").Append(entry.Value + offset_total + 1).AppendLineSeparator
                    ();
            }
            if (!(unmappedLines.Count == 0))
            {
                buffer.Append("Not mapped:").AppendLineSeparator();
                foreach (int line in unmappedLines)
                {
                    if (!linesMapping.ContainsKey(line))
                    {
                        buffer.Append(line).AppendLineSeparator();
                    }
                }
            }
        }
コード例 #4
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);
        }
コード例 #5
0
        public override TextBuffer ToJava(int indent, BytecodeMappingTracer tracer)
        {
            TextBuffer buffer = new TextBuffer();

            buffer.AppendIndent(indent);
            buffer.Append('@');
            buffer.Append(DecompilerContext.GetImportCollector().GetShortName(ExprProcessor.BuildJavaClassName
                                                                                  (className)));
            int type = GetAnnotationType();

            if (type != Annotation_Marker)
            {
                buffer.Append('(');
                bool oneLiner = type == Annotation_Single_Element || indent < 0;
                for (int i = 0; i < parNames.Count; i++)
                {
                    if (!oneLiner)
                    {
                        buffer.AppendLineSeparator().AppendIndent(indent + 1);
                    }
                    if (type != Annotation_Single_Element)
                    {
                        buffer.Append(parNames[i]);
                        buffer.Append(" = ");
                    }
                    buffer.Append(parValues[i].ToJava(0, tracer));
                    if (i < parNames.Count - 1)
                    {
                        buffer.Append(',');
                    }
                }
                if (!oneLiner)
                {
                    buffer.AppendLineSeparator().AppendIndent(indent);
                }
                buffer.Append(')');
            }
            return(buffer);
        }
コード例 #6
0
        public virtual int WriteImports(TextBuffer buffer)
        {
            int           importLinesWritten = 0;
            List <string> imports            = PackImports();

            foreach (string s in imports)
            {
                buffer.Append("import ");
                buffer.Append(s);
                buffer.Append(';');
                buffer.AppendLineSeparator();
                importLinesWritten++;
            }
            return(importLinesWritten);
        }