예제 #1
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);
    }