Exemplo n.º 1
0
        public ImportCollector(ClassesProcessor.ClassNode root)
        {
            // set of field names in this class and all its predecessors.
            string clName = root.classStruct.qualifiedName;
            int    index  = clName.LastIndexOf('/');

            if (index >= 0)
            {
                string packageName = Sharpen.Runtime.Substring(clName, 0, index);
                currentPackageSlash = packageName + '/';
                currentPackagePoint = packageName.Replace('/', '.');
            }
            else
            {
                currentPackageSlash = string.Empty;
                currentPackagePoint = string.Empty;
            }
            Dictionary <string, StructClass> classes = DecompilerContext.GetStructContext().GetClasses
                                                           ();
            LinkedList <string> queue        = new LinkedList <string>();
            StructClass         currentClass = root.classStruct;

            while (currentClass != null)
            {
                if (currentClass.superClass != null)
                {
                    queue.AddLast(currentClass.superClass.GetString());
                }
                Sharpen.Collections.AddAll(queue, currentClass.GetInterfaceNames());
                // all field names for the current class ..
                foreach (StructField f in currentClass.GetFields())
                {
                    setFieldNames.Add(f.GetName());
                }
                // .. all inner classes for the current class ..
                StructInnerClassesAttribute attribute = currentClass.GetAttribute(StructGeneralAttribute
                                                                                  .Attribute_Inner_Classes);
                if (attribute != null)
                {
                    foreach (StructInnerClassesAttribute.Entry entry in attribute.GetEntries())
                    {
                        if (entry.enclosingName != null && entry.enclosingName.Equals(currentClass.qualifiedName
                                                                                      ))
                        {
                            setInnerClassNames.Add(entry.simpleName);
                        }
                    }
                }
                // .. and traverse through parent.
                currentClass = !(queue.Count == 0) ? classes.GetOrNull(Sharpen.Collections.RemoveFirst
                                                                           (queue)) : null;
                while (currentClass == null && !(queue.Count == 0))
                {
                    currentClass = classes.GetOrNull(Sharpen.Collections.RemoveFirst(queue));
                }
            }
        }
Exemplo n.º 2
0
        private bool IsVarArgCall()
        {
            StructClass cl = DecompilerContext.GetStructContext().GetClass(classname);

            if (cl != null)
            {
                StructMethod mt = cl.GetMethod(InterpreterUtil.MakeUniqueKey(name, stringDescriptor
                                                                             ));
                if (mt != null)
                {
                    return(mt.HasModifier(ICodeConstants.Acc_Varargs));
                }
            }
            else
            {
                // TODO: tap into IDEA indices to access libraries methods details
                // try to check the class on the classpath
                MethodInfo mtd = ClasspathHelper.FindMethod(classname, name, descriptor);
                return(mtd != null && mtd.GetParameters()
                       .Any(param => Attribute.IsDefined(param, typeof(ParamArrayAttribute))));
            }
            return(false);
        }
Exemplo n.º 3
0
        public virtual string GetShortName(string fullName, bool imported)
        {
            ClassesProcessor.ClassNode node = DecompilerContext.GetClassProcessor().GetMapRootClasses
                                                  ().GetOrNull(fullName.Replace('.', '/'));
            //todo[r.sh] anonymous classes?
            string result = null;

            if (node != null && node.classStruct.IsOwn())
            {
                result = node.simpleName;
                while (node.parent != null && node.type == ClassesProcessor.ClassNode.Class_Member
                       )
                {
                    //noinspection StringConcatenationInLoop
                    result = node.parent.simpleName + '.' + result;
                    node   = node.parent;
                }
                if (node.type == ClassesProcessor.ClassNode.Class_Root)
                {
                    fullName = node.classStruct.qualifiedName;
                    fullName = fullName.Replace('/', '.');
                }
                else
                {
                    return(result);
                }
            }
            else
            {
                fullName = fullName.Replace('$', '.');
            }
            string shortName   = fullName;
            string packageName = string.Empty;
            int    lastDot     = fullName.LastIndexOf('.');

            if (lastDot >= 0)
            {
                shortName   = Sharpen.Runtime.Substring(fullName, lastDot + 1);
                packageName = Sharpen.Runtime.Substring(fullName, 0, lastDot);
            }
            StructContext context = DecompilerContext.GetStructContext();
            // check for another class which could 'shadow' this one. Three cases:
            // 1) class with the same short name in the current package
            // 2) class with the same short name in the default package
            // 3) inner class with the same short name in the current class, a super class, or an implemented interface
            bool existsDefaultClass = (context.GetClass(currentPackageSlash + shortName) != null &&
                                       !packageName.Equals(currentPackagePoint)) || (context.GetClass(shortName) !=
                                                                                     null && !(currentPackagePoint.Length == 0)) || setInnerClassNames.Contains(shortName
                                                                                                                                                                );

            // current package
            // default package
            // inner class
            if (existsDefaultClass || (mapSimpleNames.ContainsKey(shortName) && !packageName.
                                       Equals(mapSimpleNames.GetOrNull(shortName))))
            {
                //  don't return full name because if the class is a inner class, full name refers to the parent full name, not the child full name
                return(result == null ? fullName : (packageName + "." + result));
            }
            else if (!mapSimpleNames.ContainsKey(shortName))
            {
                Sharpen.Collections.Put(mapSimpleNames, shortName, packageName);
                if (!imported)
                {
                    setNotImportedNames.Add(shortName);
                }
            }
            return(result == null ? shortName : result);
        }
Exemplo n.º 4
0
        private BitSet GetAmbiguousParameters()
        {
            StructClass cl = DecompilerContext.GetStructContext().GetClass(classname);

            if (cl == null)
            {
                return(Empty_Bit_Set);
            }
            // check number of matches
            List <MethodDescriptor> matches = new List <MethodDescriptor>();

            foreach (StructMethod mt in cl.GetMethods())
            {
                if (name.Equals(mt.GetName()))
                {
                    MethodDescriptor md = MethodDescriptor.ParseDescriptor(mt.GetDescriptor());
                    if ([email protected] == [email protected])
                    {
                        for (int i = 0; i < [email protected]; i++)
                        {
                            if (md.@params[i].typeFamily != descriptor.@params[i].typeFamily)
                            {
                                goto nextMethod_continue;
                            }
                        }
                        matches.Add(md);
                    }
                }
            }
            nextMethod_break    :;
            nextMethod_continue :
            if (matches.Count == 1)
            {
                return(Empty_Bit_Set);
            }
            // check if a call is unambiguous
            StructMethod mt_1 = cl.GetMethod(InterpreterUtil.MakeUniqueKey(name, stringDescriptor
                                                                           ));

            if (mt_1 != null)
            {
                MethodDescriptor md = MethodDescriptor.ParseDescriptor(mt_1.GetDescriptor());
                if ([email protected] == lstParameters.Count)
                {
                    bool exact = true;
                    for (int i = 0; i < [email protected]; i++)
                    {
                        if (!md.@params[i].Equals(lstParameters[i].GetExprType()))
                        {
                            exact = false;
                            break;
                        }
                    }
                    if (exact)
                    {
                        return(Empty_Bit_Set);
                    }
                }
            }
            // mark parameters
            BitSet ambiguous = new BitSet([email protected]);

            for (int i = 0; i < [email protected]; i++)
            {
                VarType paramType = descriptor.@params[i];
                foreach (MethodDescriptor md in matches)
                {
                    if (!paramType.Equals(md.@params[i]))
                    {
                        ambiguous.Set(i);
                        break;
                    }
                }
            }
            return(ambiguous);
        }
Exemplo n.º 5
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);
        }