コード例 #1
0
    public static unsafe Stack <KeyValuePair <Smoke.ModuleIndex, string> > GetAbstractMethods(Smoke *smoke, short classId)
    {
        Dictionary <Smoke.ModuleIndex, string> methods =
            new Dictionary <Smoke.ModuleIndex, string>(SmokeMethodEqualityComparer.AbstractRespectingComparer);
        SmokeMethodEqualityComparer defaultComparer = SmokeMethodEqualityComparer.DefaultEqualityComparer;

        smoke->FindAllMethods(classId, methods, true);
        var abstractMethods = new Stack <KeyValuePair <Smoke.ModuleIndex, string> >();

        foreach (KeyValuePair <Smoke.ModuleIndex, string> pair in methods)
        {
            Smoke.Method *meth = pair.Key.smoke->methods + pair.Key.index;
            if ((meth->flags & (ushort)Smoke.MethodFlags.mf_purevirtual) == 0)
            {
                // only compare pure-virtuals
                continue;
            }
            abstractMethods.Push(pair);

            foreach (KeyValuePair <Smoke.ModuleIndex, string> other in methods)
            {
                // Break if we encounter our original Index. Anything after this one will be further up in the
                // hierarchy and thus can't override anything.
                if (pair.Key == other.Key)
                {
                    break;
                }

                Smoke.Method *otherMeth = other.Key.smoke->methods + other.Key.index;
                if (defaultComparer.Equals(pair.Key, other.Key))
                {
                    if ((otherMeth->flags & (ushort)Smoke.MethodFlags.mf_purevirtual) == 0)
                    {
                        // overriden with implementation
                        abstractMethods.Pop();
                    }
                    break;
                }
            }
        }

        return(abstractMethods);
    }
コード例 #2
0
    private void FillEnums()
    {
        for (short i = 1; i < this.data.Smoke->numMethodMaps; i++)
        {
            Smoke.MethodMap *map = this.data.Smoke->methodMaps + i;
            if (map->method > 0)
            {
                Smoke.Method *meth = this.data.Smoke->methods + map->method;
                if ((meth->flags & (ushort)Smoke.MethodFlags.mf_enum) > 0)
                {
                    this.eg.DefineMember(meth);
                }
            }
            else if (map->method < 0)
            {
                for (short *overload = this.data.Smoke->ambiguousMethodList + (-map->method); *overload > 0; overload++)
                {
                    Smoke.Method *meth = this.data.Smoke->methods + *overload;
                    if ((meth->flags & (ushort)Smoke.MethodFlags.mf_enum) > 0)
                    {
                        this.eg.DefineMember(meth);
                        continue;
                    }

                    // if the methods differ only by constness, we will generate special code
                    bool nextDiffersByConst = false;
                    if (*(overload + 1) > 0)
                    {
                        if (SmokeMethodEqualityComparer.EqualExceptConstness(meth, this.data.Smoke->methods + *(overload + 1)))
                        {
                            nextDiffersByConst = true;
                        }
                    }
                    if (nextDiffersByConst)
                    {
                        overload++;
                    }
                }
            }
        }
    }
コード例 #3
0
    /*
     * Adds the methods to the classes created by Run()
     */

    private void GenerateMethods()
    {
        short currentClassId = 0;

        Smoke.Class *            klass              = (Smoke.Class *)IntPtr.Zero;
        MethodsGenerator         methgen            = null;
        AttributeGenerator       attrgen            = null;
        CodeTypeDeclaration      type               = null;
        List <Smoke.ModuleIndex> alreadyImplemented = new List <Smoke.ModuleIndex>();

        this.FillEnums();

        for (short i = 1; i < data.Smoke->numMethodMaps; i++)
        {
            Smoke.MethodMap *map = data.Smoke->methodMaps + i;

            if (currentClassId != map->classId)
            {
                // we encountered a new class
                if (attrgen != null)
                {
                    // generate inherited methods
                    this.GenerateInheritedMethods(klass, methgen, attrgen, alreadyImplemented);

                    // generate all scheduled attributes
                    attrgen.Run();

                    if (PostMembersHooks != null)
                    {
                        PostMembersHooks(data.Smoke, klass, type);
                    }
                    methgen.GenerateProperties();
                }

                currentClassId = map->classId;
                klass          = data.Smoke->classes + currentClassId;
                type           = data.SmokeTypeMap[(IntPtr)klass];

                alreadyImplemented.Clear();
                attrgen = new AttributeGenerator(data, translator, type);
                methgen = new MethodsGenerator(data, translator, type, klass);
            }

            string mungedName = ByteArrayManager.GetString(data.Smoke->methodNames[map->name]);
            if (map->method > 0)
            {
                Smoke.Method *meth = data.Smoke->methods + map->method;
                if ((meth->flags & (ushort)Smoke.MethodFlags.mf_enum) > 0)
                {
                    continue;
                }

                if ((meth->flags & (ushort)Smoke.MethodFlags.mf_property) > 0 &&               // non-virtual properties are excluded
                    (meth->flags & (ushort)Smoke.MethodFlags.mf_virtual) == 0 &&
                    (meth->flags & (ushort)Smoke.MethodFlags.mf_purevirtual) == 0)
                {
                    continue;
                }
                if ((meth->flags & (ushort)Smoke.MethodFlags.mf_attribute) > 0)
                {
                    attrgen.ScheduleAttributeAccessor(meth);
                    continue;
                }

                methgen.GenerateMethod(map->method, mungedName);
                alreadyImplemented.Add(new Smoke.ModuleIndex(data.Smoke, map->method));
            }
            else if (map->method < 0)
            {
                for (short *overload = data.Smoke->ambiguousMethodList + (-map->method); *overload > 0; overload++)
                {
                    Smoke.Method *meth = data.Smoke->methods + *overload;
                    if ((meth->flags & (ushort)Smoke.MethodFlags.mf_enum) > 0)
                    {
                        continue;
                    }

                    if ((meth->flags & (ushort)Smoke.MethodFlags.mf_property) > 0 &&                   // non-virtual properties are excluded
                        (meth->flags & (ushort)Smoke.MethodFlags.mf_virtual) == 0 &&
                        (meth->flags & (ushort)Smoke.MethodFlags.mf_purevirtual) == 0)
                    {
                        continue;
                    }
                    if ((meth->flags & (ushort)Smoke.MethodFlags.mf_attribute) > 0)
                    {
                        attrgen.ScheduleAttributeAccessor(meth);
                        continue;
                    }

                    // if the methods differ only by constness, we will generate special code
                    bool nextDiffersByConst = false;
                    if (*(overload + 1) > 0)
                    {
                        if (SmokeMethodEqualityComparer.EqualExceptConstness(meth, data.Smoke->methods + *(overload + 1)))
                        {
                            nextDiffersByConst = true;
                        }
                    }

                    methgen.GenerateMethod(*overload, mungedName);
                    alreadyImplemented.Add(new Smoke.ModuleIndex(data.Smoke, *overload));
                    if (nextDiffersByConst)
                    {
                        overload++;
                    }
                }
            }
        }

        // Generate the last scheduled attributes
        attrgen.Run();
        // Generate remaining inherited methods
        this.GenerateInheritedMethods(klass, methgen, attrgen, alreadyImplemented);

        if (PostMembersHooks != null)
        {
            PostMembersHooks(data.Smoke, klass, type);
        }
        methgen.GenerateProperties();
        AddMissingOperators();
    }