Пример #1
0
 public void AddClassToDeclaringType(TypeDefinition cilType, JavaClass jclass)
 {
     if (jclass.IsInnerClass())
     {
         var outerName = jclass.OuterAndInnerClasses[0].OuterLongName;
         if (typeMap.TryGetValue(outerName, out var cilOuterTypeRef) &&
             cilOuterTypeRef is TypeDefinition cilOuterType)
         {
             foreach (var nestedType in cilOuterType.NestedTypes)
             {
                 if (nestedType.Name == cilType.Name)
                 {
                     Console.WriteLine($"skipping duplicate class '{nestedType.FullName}'");
                     return;
                 }
             }
             cilOuterType.NestedTypes.Add(cilType);
         }
         else
         {
             throw new JavaException(
                       $"outer class '{outerName}' not found for inner class", Where);
         }
     }
     else
     {
         module.Types.Add(cilType);
     }
 }
Пример #2
0
    public bool CreateCilTypeForClass(JavaClass jclass)
    {
        var name = jclass.Name;

        if (typeMap.TryGetValue(name, out _) ||
            jclass.IsInnerClass() &&
            (name.StartsWith("java.lang.Object$") ||
             name.StartsWith("java.lang.String$")))
        {
            Console.WriteLine($"skipping duplicate class '{name}'");
            return(false);
        }

        string         nsName, clsName;
        TypeAttributes attrs = 0;

        if (jclass.IsInnerClass())
        {
            nsName  = string.Empty;
            clsName = jclass.OuterAndInnerClasses[0].InnerShortName;

            if (!string.IsNullOrEmpty(clsName))
            {
                int idx = name.LastIndexOf('$');
                if (idx != -1 && idx + 1 < name.Length)
                {
                    clsName = name.Substring(idx + 1);
                }
            }
            if (string.IsNullOrEmpty(clsName) || (!Char.IsLetter(clsName[0])))
            {
                clsName = "autogenerated_" + jclass.GetHashCode().ToString("X8");
            }

            if ((jclass.Flags & JavaAccessFlags.ACC_PUBLIC) != 0)
            {
                attrs = TypeAttributes.NestedPublic;
            }
            else if ((jclass.Flags & JavaAccessFlags.ACC_PRIVATE) != 0)
            {
                attrs = TypeAttributes.NestedPrivate;
            }
            else if ((jclass.Flags & JavaAccessFlags.ACC_PROTECTED) != 0)
            {
                attrs = TypeAttributes.NestedFamORAssem;
            }
            else
            {
                attrs = TypeAttributes.NestedAssembly;
            }
        }
        else
        {
            int n = jclass.PackageNameLength;
            nsName = name.Substring(0, n);
            if (name[n] == '.')
            {
                n++;
            }
            clsName = name.Substring(n);
            if ((jclass.Flags & JavaAccessFlags.ACC_PUBLIC) != 0)
            {
                attrs |= TypeAttributes.Public;
            }
        }

        if ((jclass.Flags & JavaAccessFlags.ACC_ABSTRACT) != 0)
        {
            attrs |= TypeAttributes.Abstract;
        }
        if ((jclass.Flags & JavaAccessFlags.ACC_INTERFACE) != 0)
        {
            attrs |= TypeAttributes.Interface;
        }
        if ((jclass.Flags & JavaAccessFlags.ACC_FINAL) != 0)
        {
            attrs |= TypeAttributes.Sealed;
        }

        var newType = new TypeDefinition(nsName, clsName, attrs);

        newType.CustomAttributes.Add(new CustomAttribute(retainNameAttributeConstructor));

        typeMap[name] = newType;
        return(true);
    }
Пример #3
0
    public void LinkCilTypesByClass(TypeDefinition cilType, JavaClass jclass)
    {
        if (jclass.IsInnerClass())
        {
            var outerName = jclass.OuterAndInnerClasses[0].OuterLongName;
            if (typeMap.TryGetValue(outerName, out var cilOuterTypeRef) &&
                cilOuterTypeRef is TypeDefinition cilOuterType)
            {
                foreach (var nestedType in cilOuterType.NestedTypes)
                {
                    if (nestedType.Name == cilType.Name)
                    {
                        Console.WriteLine($"skipping duplicate class '{nestedType.FullName}'");
                        return;
                    }
                }
                cilOuterType.NestedTypes.Add(cilType);
            }
            else
            {
                throw new JavaException(
                          $"outer class '{outerName}' not found for inner class", Where);
            }
        }
        else
        {
            module.Types.Add(cilType);
        }

        var superName = jclass.Super;

        if (superName == "java.lang.Enum")
        {
            superName = null;
        }

        if (superName != null)
        {
            if (typeMap.TryGetValue(superName, out var cilSuperTypeRef))
            {
                if (cilType.IsInterface)
                {
                    if (superName != "java.lang.Object")
                    {
                        cilType.Interfaces.Add(
                            new InterfaceImplementation(cilSuperTypeRef));
                    }
                }
                else
                {
                    if (jclass.Name == "java.lang.Throwable" &&
                        superName == "java.lang.Object")
                    {
                        cilSuperTypeRef = systemException;
                    }
                    cilType.BaseType = cilSuperTypeRef;
                }
                CilTypeAddUse(cilSuperTypeRef);
            }
            else
            {
                throw new JavaException($"super class '{superName}' not found", Where);
            }
        }

        if (jclass.Interfaces != null)
        {
            foreach (var interfaceName in jclass.Interfaces)
            {
                if (typeMap.TryGetValue(interfaceName, out var cilInterfaceTypeRef))
                {
                    if (cilInterfaceTypeRef.Resolve()?.IsInterface == true)
                    {
                        cilType.Interfaces.Add(
                            new InterfaceImplementation(cilInterfaceTypeRef));
                        CilTypeAddUse(cilInterfaceTypeRef);
                    }
                }
                else
                {
                    throw new JavaException($"interface '{interfaceName}' not found", Where);
                }
            }
        }
    }