예제 #1
0
        private IEnumerable <CCodeUnit> BuildUnit(ITypeSymbol type, IAssembliesInfoResolver assembliesInfoResolver)
        {
            var namedTypeSymbol = (INamedTypeSymbol)type;

            var unit = new CCodeUnit(type);

            var isNotModule = type.Name != "<Module>";

            // Class
            var isNotInterfaceOrModule = isNotModule && type.TypeKind != TypeKind.Interface;
            var methodSymbols          = type.GetMembers().OfType <IMethodSymbol>().ToList();
            var hasStaticConstructor   = methodSymbols.Any(m => m.MethodKind == MethodKind.StaticConstructor);

            // to support generic virtual methods
            #region Virtual Generic methods support
            var methodsTableType = "__methods_table".ToType();
            foreach (var typeParameter in namedTypeSymbol.GetTemplateParameters().Where(t => t.HasConstructorConstraint))
            {
                this.BuildField(new FieldImpl {
                    Type = methodsTableType, Name = "construct_" + typeParameter.Name
                }, unit, false);
            }
            #endregion

            foreach (var field in type.GetMembers().OfType <IFieldSymbol>())
            {
                this.BuildField(field, unit, hasStaticConstructor);
            }

            foreach (var @event in type.GetMembers().OfType <IEventSymbol>())
            {
                this.BuildField(new FieldImpl(@event), unit, hasStaticConstructor);
            }

            if (hasStaticConstructor)
            {
                BuildStaticConstructorVariables(type, unit);
            }

            if (isNotModule)
            {
                ////BuildTypeHolderVariables(type, unit);
                BuildTypeDescriptorVariables(type, unit);
            }

            var constructors = methodSymbols.Where(m => m.MethodKind == MethodKind.Constructor);
            foreach (var method in constructors)
            {
                this.BuildMethod(method, unit);
            }

            var finalizationRequired = type.BaseType != null && type.GetMembers().OfType <IMethodSymbol>().Any(m => m.MethodKind == MethodKind.Destructor);
            var isAtomicType         = type.IsAtomicType();
            if (isNotInterfaceOrModule && !type.IsAbstract)
            {
                unit.Declarations.Add(new CCodeNewOperatorDeclaration(namedTypeSymbol, finalizationRequired));
                unit.Declarations.Add(new CCodeNewOperatorDeclaration(namedTypeSymbol, finalizationRequired, debugVersion: true));
                unit.Declarations.Add(new CCodeNewOperatorDeclaration(namedTypeSymbol, finalizationRequired, true));
                unit.Declarations.Add(new CCodeNewOperatorDeclaration(namedTypeSymbol, finalizationRequired, true, true));
            }

            if (!isAtomicType && type.TypeKind != TypeKind.Interface)
            {
                unit.Declarations.Add(new CCodeGetTypeDescriptorDeclaration(namedTypeSymbol));
            }

            if (type.IsPrimitiveValueType() || type.TypeKind == TypeKind.Enum)
            {
                unit.Declarations.Add(new CCodeSpecialTypeOrEnumConstructorDeclaration(namedTypeSymbol, false));
            }

            /*
             * if (type.IsIntPtrType())
             * {
             *  unit.Declarations.Add(new CCodeSpecialTypeOrEnumConstructorDeclaration((INamedTypeSymbol)type, true));
             * }
             */

            // to support RuntimeType initialization
            if (type.IsRuntimeType())
            {
                unit.Declarations.Add(new CCodeRuntimeTypeConstructorDeclaration(namedTypeSymbol, true));
            }

            if (type.IsPrimitiveValueType() || type.TypeKind == TypeKind.Enum || type.IsIntPtrType())
            {
                unit.Declarations.Add(new CCodeCastOperatorDeclaration(namedTypeSymbol));
            }

            if (type.TypeKind == TypeKind.Struct)
            {
                unit.Declarations.Add(new CCodeArrowOperatorDeclaration(namedTypeSymbol));
            }

            if (isNotInterfaceOrModule)
            {
                // add internal infrustructure
                unit.Declarations.Add(new CCodeGetTypeVirtualMethodDeclaration(namedTypeSymbol));
                unit.Definitions.Add(new CCodeGetTypeVirtualMethodDefinition(namedTypeSymbol));
                unit.Declarations.Add(new CCodeIsTypeVirtualMethodDeclaration(namedTypeSymbol));
                unit.Definitions.Add(new CCodeIsTypeVirtualMethodDefinition(namedTypeSymbol));
                unit.Declarations.Add(new CCodeGetInterfaceVirtualMethodDeclaration(namedTypeSymbol));
                unit.Definitions.Add(new CCodeGetInterfaceVirtualMethodDefinition(namedTypeSymbol));
                if (!type.IsAbstract)
                {
                    unit.Declarations.Add(new CCodeCloneVirtualMethod(namedTypeSymbol));
                    unit.Declarations.Add(new CCodeGetSizeVirtualMethod(namedTypeSymbol));
                }

                if (type.SpecialType == SpecialType.System_Object)
                {
                    unit.Declarations.Add(new CCodeHashVirtualMethod(namedTypeSymbol));
                    unit.Declarations.Add(new CCodeEqualsVirtualMethod(namedTypeSymbol));
                }
            }

            if (type.TypeKind == TypeKind.Interface)
            {
                unit.Declarations.Add(new CCodeObjectCastOperatorDeclaration(namedTypeSymbol));
            }

            if (type.SpecialType == SpecialType.System_Array)
            {
                unit.Declarations.Add(new CCodeNewOperatorPointerDeclaration(namedTypeSymbol));
                unit.Declarations.Add(new CCodeGetArrayElementSizeVirtualMethod(namedTypeSymbol));
                unit.Declarations.Add(new CCodeIsPrimitiveTypeArrayVirtualMethod(namedTypeSymbol));
            }

            if (type.TypeKind == TypeKind.Interface)
            {
                // add all methods from all interfaces
                foreach (var method in type.EnumerateInterfaceMethods())
                {
                    unit.Declarations.Add(new CCodeMethodDeclaration(type, method));
                }
            }

            foreach (var method in methodSymbols.Where(m => m.MethodKind != MethodKind.Constructor))
            {
                this.BuildMethod(method, unit);
            }

            // write interface wrappers
            foreach (var iface in namedTypeSymbol.Interfaces)
            {
                unit.Declarations.Add(new CCodeClassDeclaration(new CCodeInterfaceWrapperClass(namedTypeSymbol, iface)));
                unit.Declarations.Add(new CCodeInterfaceCastOperatorDeclaration(namedTypeSymbol, iface));
            }

            if (isNotModule)
            {
                BuildMethodTableVariables(type, unit);
                ////BuildRuntimeInfoVariables(type, unit);
            }

            // transition all methods which have body into source file
            foreach (var declaration in unit.Declarations.OfType <CCodeMethodDeclaration>().Where(m => m.MethodBodyOpt != null))
            {
                declaration.ToDefinition(unit.Definitions, namedTypeSymbol);
            }

            yield return(unit);

            // TypeHolder
            if (!isNotModule)
            {
                yield break;
            }

            // return type holder class
            var typeHolderType = (TypeImpl)TypeImpl.Wrap(type);

            if (!type.IsAnonymousType())
            {
                typeHolderType.Name         = typeHolderType.Name + "__type";
                typeHolderType.MetadataName = typeHolderType.MetadataName + "__type";
            }
            else
            {
                var namedType = (INamedTypeSymbol)type;
                typeHolderType.Name         = namedType.GetAnonymousTypeName() + "__type";
                typeHolderType.MetadataName = namedType.GetAnonymousTypeName() + "__type";
            }

            typeHolderType.BaseType      = null;
            typeHolderType.TypeKind      = TypeKind.Struct;
            typeHolderType.Interfaces    = ImmutableArray <INamedTypeSymbol> .Empty;
            typeHolderType.AllInterfaces = ImmutableArray <INamedTypeSymbol> .Empty;
            typeHolderType.SpecialType   = SpecialType.None;

            var unitTypeHolder = new CCodeUnit(typeHolderType);
            BuildTypeHolderVariables(typeHolderType, unitTypeHolder);
            ////BuildMethodTableVariables(typeHolderType, unitTypeHolder);
            BuildRuntimeInfoVariables(typeHolderType, type, unitTypeHolder);

            yield return(unitTypeHolder);
        }
예제 #2
0
        private IEnumerable <CCodeUnit> BuildUnit(ITypeSymbol type, IAssembliesInfoResolver assembliesInfoResolver)
        {
            var unit = new CCodeUnit(type);

            var isNotModule            = type.Name != "<Module>";
            var isNotInterfaceOrModule = isNotModule && type.TypeKind != TypeKind.Interface;
            var methodSymbols          = type.GetMembers().OfType <IMethodSymbol>().ToList();
            var hasStaticConstructor   = methodSymbols.Any(m => m.MethodKind == MethodKind.StaticConstructor);

            foreach (var field in type.GetMembers().OfType <IFieldSymbol>())
            {
                this.BuildField(field, unit, hasStaticConstructor);
            }

            foreach (var @event in type.GetMembers().OfType <IEventSymbol>())
            {
                this.BuildField(new FieldImpl(@event), unit, hasStaticConstructor);
            }

            if (hasStaticConstructor)
            {
                BuildStaticConstructorVariables(type, unit);
            }

            if (isNotModule)
            {
                ////BuildTypeHolderVariables(type, unit);
                BuildTypeDescriptorVariables(type, unit);
            }

            var constructors = methodSymbols.Where(m => m.MethodKind == MethodKind.Constructor);

            foreach (var method in constructors)
            {
                this.BuildMethod(method, unit);
            }

            var finalizationRequired = type.BaseType != null && type.GetMembers().OfType <IMethodSymbol>().Any(m => m.MethodKind == MethodKind.Destructor);
            var isAtomicType         = type.IsAtomicType();
            var namedTypeSymbol      = (INamedTypeSymbol)type;

            if (isNotInterfaceOrModule)
            {
                unit.Declarations.Add(new CCodeNewOperatorDeclaration(namedTypeSymbol, finalizationRequired));
                unit.Declarations.Add(new CCodeNewOperatorDeclaration(namedTypeSymbol, finalizationRequired, debugVersion: true));
                unit.Declarations.Add(new CCodeNewOperatorDeclaration(namedTypeSymbol, finalizationRequired, true));
                unit.Declarations.Add(new CCodeNewOperatorDeclaration(namedTypeSymbol, finalizationRequired, true, true));
            }

            if (!isAtomicType && type.TypeKind != TypeKind.Interface)
            {
                unit.Declarations.Add(new CCodeGetTypeDescriptorDeclaration(namedTypeSymbol));
            }

            if (type.IsPrimitiveValueType() || type.TypeKind == TypeKind.Enum)
            {
                unit.Declarations.Add(new CCodeSpecialTypeOrEnumConstructorDeclaration(namedTypeSymbol, false));
            }

            /*
             * if (type.IsIntPtrType())
             * {
             *  unit.Declarations.Add(new CCodeSpecialTypeOrEnumConstructorDeclaration((INamedTypeSymbol)type, true));
             * }
             */

            // to support RuntimeType initialization
            if (type.IsRuntimeType())
            {
                unit.Declarations.Add(new CCodeRuntimeTypeConstructorDeclaration(namedTypeSymbol, true));
            }

            if (type.IsPrimitiveValueType() || type.TypeKind == TypeKind.Enum || type.IsIntPtrType())
            {
                unit.Declarations.Add(new CCodeCastOperatorDeclaration(namedTypeSymbol));
            }

            if (type.TypeKind == TypeKind.Struct)
            {
                unit.Declarations.Add(new CCodeArrowOperatorDeclaration(namedTypeSymbol));
            }

            if (isNotInterfaceOrModule)
            {
                // add internal infrustructure
                unit.Declarations.Add(new CCodeGetTypeVirtualMethodDeclaration(namedTypeSymbol));
                unit.Definitions.Add(new CCodeGetTypeVirtualMethodDefinition(namedTypeSymbol));
                unit.Declarations.Add(new CCodeIsTypeVirtualMethodDeclaration(namedTypeSymbol));
                unit.Definitions.Add(new CCodeIsTypeVirtualMethodDefinition(namedTypeSymbol));
                unit.Declarations.Add(new CCodeGetInterfaceVirtualMethodDeclaration(namedTypeSymbol));
                unit.Definitions.Add(new CCodeGetInterfaceVirtualMethodDefinition(namedTypeSymbol));
                if (!type.IsAbstract)
                {
                    unit.Declarations.Add(new CCodeCloneVirtualMethod(namedTypeSymbol));
                    unit.Declarations.Add(new CCodeGetSizeVirtualMethod(namedTypeSymbol));
                }

                if (type.SpecialType == SpecialType.System_Object)
                {
                    unit.Declarations.Add(new CCodeHashVirtualMethod(namedTypeSymbol));
                    unit.Declarations.Add(new CCodeEqualsVirtualMethod(namedTypeSymbol));
                }
            }

            if (type.TypeKind == TypeKind.Interface)
            {
                unit.Declarations.Add(new CCodeObjectCastOperatorDeclaration(namedTypeSymbol));
            }

            if (type.SpecialType == SpecialType.System_Array)
            {
                unit.Declarations.Add(new CCodeNewOperatorPointerDeclaration(namedTypeSymbol));
                unit.Declarations.Add(new CCodeGetArrayElementSizeVirtualMethod(namedTypeSymbol));
                unit.Declarations.Add(new CCodeIsPrimitiveTypeArrayVirtualMethod(namedTypeSymbol));
            }

            if (type.TypeKind == TypeKind.Interface)
            {
                // add all methods from all interfaces
                foreach (var method in type.EnumerateInterfaceMethods())
                {
                    unit.Declarations.Add(new CCodeMethodDeclaration(type, method));
                }
            }

            foreach (var method in methodSymbols.Where(m => m.MethodKind != MethodKind.Constructor))
            {
                this.BuildMethod(method, unit);
            }

            if (isNotModule)
            {
                BuildMethodTableVariables(type, unit);
                ////BuildRuntimeInfoVariables(type, unit);
            }

            if (isNotInterfaceOrModule)
            {
                // append interface calls
                foreach (var interfaceMethod in type.EnumerateInterfaceMethods())
                {
                    var method = interfaceMethod;
                    var implementationForInterfaceMember = type.FindImplementationForInterfaceMember(interfaceMethod) as IMethodSymbol;
                    if (implementationForInterfaceMember != null &&
                        implementationForInterfaceMember.ExplicitInterfaceImplementations.Any(ei => ei.Equals(method)))
                    {
                        continue;
                    }

                    Debug.Assert(implementationForInterfaceMember != null, "Method for interface can't be found");
                    unit.Declarations.Add(new CCodeInterfaceMethodAdapterDeclaration(type, interfaceMethod, implementationForInterfaceMember));
                    unit.Definitions.Add(new CCodeInterfaceMethodAdapterDefinition(type, interfaceMethod, implementationForInterfaceMember));
                }
            }

            yield return(unit);

            if (!isNotModule)
            {
                yield break;
            }

            // return type holder class
            var typeHolderType = (TypeImpl)TypeImpl.Wrap(type);

            if (!type.IsAnonymousType())
            {
                typeHolderType.Name         = typeHolderType.Name + "__type";
                typeHolderType.MetadataName = typeHolderType.MetadataName + "__type";
            }
            else
            {
                var namedType = (INamedTypeSymbol)type;
                typeHolderType.Name         = namedType.GetAnonymousTypeName() + "__type";
                typeHolderType.MetadataName = namedType.GetAnonymousTypeName() + "__type";
            }

            typeHolderType.BaseType      = null;
            typeHolderType.TypeKind      = TypeKind.Struct;
            typeHolderType.Interfaces    = ImmutableArray <INamedTypeSymbol> .Empty;
            typeHolderType.AllInterfaces = ImmutableArray <INamedTypeSymbol> .Empty;
            typeHolderType.SpecialType   = SpecialType.None;

            var unitTypeHolder = new CCodeUnit(typeHolderType);

            BuildTypeHolderVariables(typeHolderType, unitTypeHolder);
            ////BuildMethodTableVariables(typeHolderType, unitTypeHolder);
            BuildRuntimeInfoVariables(typeHolderType, type, unitTypeHolder);

            yield return(unitTypeHolder);
        }
예제 #3
0
        private CCodeUnit BuildUnit(ITypeSymbol type, IAssembliesInfoResolver assembliesInfoResolver)
        {
            var unit = new CCodeUnit(type);

            var methodSymbols        = type.GetMembers().OfType <IMethodSymbol>().ToList();
            var hasStaticConstructor = methodSymbols.Any(m => m.MethodKind == MethodKind.StaticConstructor);

            foreach (var field in type.GetMembers().OfType <IFieldSymbol>())
            {
                this.BuildField(field, unit, hasStaticConstructor);
            }

            if (hasStaticConstructor)
            {
                BuildStaticConstructorVariables(type, unit);
            }

            if (type.Name != "<Module>")
            {
                BuildTypeHolderVariables(type, unit);
            }

            var constructors = methodSymbols.Where(m => m.MethodKind == MethodKind.Constructor);

            foreach (var method in constructors)
            {
                this.BuildMethod(method, unit);
            }

            if (type.TypeKind != TypeKind.Interface && type.BaseType == null && type.Name != "<Module>")
            {
                unit.Declarations.Add(new CCodeNewOperatorDeclaration((INamedTypeSymbol)type));
                unit.Declarations.Add(new CCodeNewOperatorWithSizeDeclaration((INamedTypeSymbol)type));
            }

            if (type.IsPrimitiveValueType() || type.TypeKind == TypeKind.Enum)
            {
                unit.Declarations.Add(new CCodeSpecialTypeOrEnumConstructorDeclaration((INamedTypeSymbol)type));
            }

            if (type.IsPrimitiveValueType() || type.TypeKind == TypeKind.Enum || type.IsIntPtrType())
            {
                unit.Declarations.Add(new CCodeCastOperatorDeclaration((INamedTypeSymbol)type));
            }

            if (type.TypeKind == TypeKind.Struct)
            {
                unit.Declarations.Add(new CCodeArrowOperatorDeclaration((INamedTypeSymbol)type));
            }

            if (type.Name != "<Module>" && type.TypeKind != TypeKind.Interface)
            {
                // add internal infrustructure
                unit.Declarations.Add(new CCodeGetTypeVirtualMethodDeclaration((INamedTypeSymbol)type));
                unit.Definitions.Add(new CCodeGetTypeVirtualMethodDefinition((INamedTypeSymbol)type));
                unit.Declarations.Add(new CCodeIsTypeVirtualMethodDeclaration((INamedTypeSymbol)type));
                unit.Definitions.Add(new CCodeIsTypeVirtualMethodDefinition((INamedTypeSymbol)type));
                unit.Declarations.Add(new CCodeGetInterfaceVirtualMethodDeclaration((INamedTypeSymbol)type));
                unit.Definitions.Add(new CCodeGetInterfaceVirtualMethodDefinition((INamedTypeSymbol)type));
                if (!type.IsAbstract)
                {
                    unit.Declarations.Add(new CCodeCloneVirtualMethod((INamedTypeSymbol)type));
                }
            }

            if (type.TypeKind == TypeKind.Interface)
            {
                unit.Declarations.Add(new CCodeObjectCastOperatorDeclaration((INamedTypeSymbol)type));
            }

            if (type.SpecialType == SpecialType.System_Array)
            {
                unit.Declarations.Add(new CCodeGetArrayElementSizeVirtualMethod((INamedTypeSymbol)type));
            }

            if (type.TypeKind == TypeKind.Interface)
            {
                // add all methods from all interfaces
                foreach (var method in type.AllInterfaces.SelectMany(i => i.GetMembers().OfType <IMethodSymbol>()))
                {
                    unit.Declarations.Add(new CCodeMethodDeclaration(method));
                }
            }

            foreach (var method in methodSymbols.Where(m => m.MethodKind != MethodKind.Constructor))
            {
                this.BuildMethod(method, unit);
            }

            if (type.TypeKind != TypeKind.Interface)
            {
                // append interface calls
                foreach (var interfaceMethod in type.AllInterfaces.SelectMany(i => i.GetMembers().OfType <IMethodSymbol>()))
                {
                    var method = interfaceMethod;
                    var implementationForInterfaceMember = type.FindImplementationForInterfaceMember(interfaceMethod) as IMethodSymbol;
                    if (implementationForInterfaceMember != null &&
                        implementationForInterfaceMember.ExplicitInterfaceImplementations.Any(ei => ei.Equals(method)))
                    {
                        continue;
                    }

                    Debug.Assert(implementationForInterfaceMember != null, "Method for interface can't be found");
                    unit.Declarations.Add(new CCodeInterfaceMethodAdapterDeclaration(interfaceMethod, implementationForInterfaceMember));
                    unit.Definitions.Add(new CCodeInterfaceMethodAdapterDefinition(type, interfaceMethod, implementationForInterfaceMember));
                }
            }

            return(unit);
        }