示例#1
0
        private static void BuildTypeDescriptorVariables(ITypeSymbol type, CCodeUnit unit)
        {
            if (!type.IsAtomicType())
            {
                var namedTypeSymbol = (INamedTypeSymbol)type;

                // add type descriptor
                // add call flag for static constructor
                var typeDescriptorHolderField = new FieldImpl
                {
                    Name = "__type_descriptor",
                    Type =
                        new NamedTypeImpl
                    {
                        Name     = "GC_descr",
                        TypeKind = TypeKind.TypeParameter
                    },
                    ContainingType      = namedTypeSymbol,
                    ContainingNamespace = type.ContainingNamespace,
                    IsStatic            = true,
                    HasConstantValue    = true,
                    ConstantValue       = 0
                };

                unit.Declarations.Add(new CCodeFieldDeclaration(typeDescriptorHolderField)
                {
                    DoNotWrapStatic = true
                });
                unit.Definitions.Add(new CCodeFieldDefinition(typeDescriptorHolderField)
                {
                    DoNotWrapStatic = true
                });
            }
        }
示例#2
0
        private static void BuildMethodTableVariables(ITypeSymbol type, CCodeUnit unit)
        {
            // add methods table
            unit.Declarations.Add(new CCodeClassDeclaration(new CCodeMethodsTableClass((INamedTypeSymbol)type)));

            var tableMethodsField = new FieldImpl
            {
                Name = "_methods_table",
                Type =
                    new NamedTypeImpl
                {
                    Name             = "__type_methods_table",
                    ContainingSymbol = type,
                    TypeKind         = TypeKind.Unknown,
                    ContainingType   = (INamedTypeSymbol)type
                },
                ContainingType      = (INamedTypeSymbol)type,
                ContainingNamespace = type.ContainingNamespace,
                IsStatic            = true
            };

            unit.Declarations.Add(new CCodeFieldDeclaration(tableMethodsField)
            {
                DoNotWrapStatic = true
            });
            unit.Definitions.Add(new CCodeFieldDefinition(tableMethodsField)
            {
                DoNotWrapStatic = true
            });
        }
示例#3
0
        private static string GetRelativePath(CCodeUnit unit, out int nestedLevel)
        {
            var enumNamespaces = unit.Type.ContainingNamespace.EnumNamespaces().Where(n => !n.IsGlobalNamespace).ToList();

            nestedLevel = enumNamespaces.Count();
            return(String.Join("\\", enumNamespaces.Select(n => n.MetadataName.ToString().CleanUpNameAllUnderscore())));
        }
示例#4
0
        private static void BuildRuntimeInfoVariables(ITypeSymbol type, CCodeUnit unit)
        {
            // add runtimeinfo
            var namedTypeSymbol  = (INamedTypeSymbol)type;
            var runtimeInfoField = new FieldImpl
            {
                Name = "__rt_info",
                Type = new NamedTypeImpl {
                    Name = "__runtimetype_info", TypeKind = TypeKind.Unknown,
                },
                ContainingType      = namedTypeSymbol,
                ContainingNamespace = type.ContainingNamespace,
                IsStatic            = true,
                HasConstantValue    = true,
                ConstantValue       = CreateRuntimeInfoInitialization(namedTypeSymbol)
            };

            unit.Declarations.Add(new CCodeFieldDeclaration(runtimeInfoField)
            {
                DoNotWrapStatic = true
            });
            unit.Definitions.Add(new CCodeFieldDefinition(runtimeInfoField)
            {
                DoNotWrapStatic = true
            });
        }
示例#5
0
        private string GetPath(CCodeUnit unit, out int nestedLevel, string ext = ".cpp", string folder = "src", bool doNotCreateFolder = false)
        {
            var fileRelativePath = GetRelativePath(unit, out nestedLevel);
            var fullDirPath      = Path.Combine(this.currentFolder, folder, fileRelativePath);

            if (!doNotCreateFolder && !Directory.Exists(fullDirPath))
            {
                Directory.CreateDirectory(fullDirPath);
            }

            var fullPath = Path.Combine(fullDirPath, string.Concat(unit.Type.GetTypeName().CleanUpNameAllUnderscore(), ext));

            return(fullPath);
        }
示例#6
0
        private void BuildField(IFieldSymbol field, CCodeUnit unit, bool hasStaticConstructor)
        {
            if (field.IsConst && field.Type.SpecialType != SpecialType.System_Decimal && field.Type.SpecialType != SpecialType.System_DateTime)
            {
                return;
            }

            unit.Declarations.Add(new CCodeFieldDeclaration(field)
            {
                DoNotWrapStatic = !hasStaticConstructor
            });
            if (field.IsStatic)
            {
                unit.Definitions.Add(new CCodeFieldDefinition(field)
                {
                    DoNotWrapStatic = !hasStaticConstructor
                });
            }
        }
示例#7
0
        private static void WriteForwardDeclarationForUnit(CCodeUnit unit, IndentedTextWriter itw, CCodeWriterText c)
        {
            var namedTypeSymbol = (INamedTypeSymbol)unit.Type;

            foreach (var namespaceNode in namedTypeSymbol.ContainingNamespace.EnumNamespaces())
            {
                itw.Write("namespace ");
                c.WriteNamespaceName(namespaceNode);
                itw.Write(" { ");
            }

            if (namedTypeSymbol.IsGenericType)
            {
                c.WriteTemplateDeclaration(namedTypeSymbol);
            }

            itw.Write(namedTypeSymbol.IsValueType ? "struct" : "class");
            itw.Write(" ");
            c.WriteTypeName(namedTypeSymbol, false);
            itw.Write("; ");

            if (namedTypeSymbol.TypeKind == TypeKind.Enum)
            {
                WriteEnum(itw, c, namedTypeSymbol);
            }

            foreach (var namespaceNode in namedTypeSymbol.ContainingNamespace.EnumNamespaces())
            {
                itw.Write("}");
            }

            itw.WriteLine();

            if (namedTypeSymbol.SpecialType == SpecialType.System_Object || namedTypeSymbol.SpecialType == SpecialType.System_String)
            {
                itw.Write("typedef ");
                c.WriteType(namedTypeSymbol, suppressReference: true, allowKeywords: false);
                itw.Write(" ");
                c.WriteTypeName(namedTypeSymbol);
                itw.WriteLine(";");
            }
        }
示例#8
0
        private static void BuildTypeHolderVariables(ITypeSymbol type, CCodeUnit unit)
        {
            // add call flag for static constructor
            var namedTypeSymbol = (INamedTypeSymbol)type;
            var runtimeType     = "RuntimeType".ToSystemType(true);
            var typeHolderField = new FieldImpl
            {
                Name = "__type",
                Type =
                    runtimeType,
                ContainingType      = namedTypeSymbol,
                ContainingNamespace = type.ContainingNamespace,
                IsStatic            = true,
                HasConstantValue    = true,
                ConstantValue       = new ObjectCreationExpression
                {
                    Type      = runtimeType,
                    Arguments =
                    {
                        new AddressOfOperator {
                            Operand = new FieldAccess{
                                Field = new FieldImpl{
                                    ContainingType = namedTypeSymbol, Name = "__rt_info", IsStatic = true
                                }
                            }
                        }
                    },
                    CppClassInitialization = true
                }
            };

            unit.Declarations.Add(new CCodeFieldDeclaration(typeHolderField)
            {
                DoNotWrapStatic = true
            });
            unit.Definitions.Add(new CCodeFieldDefinition(typeHolderField)
            {
                DoNotWrapStatic = true
            });
        }
示例#9
0
        private static void BuildStaticConstructorVariables(ITypeSymbol type, CCodeUnit unit)
        {
            // add call flag for static constructor
            var cctorCalledField = new FieldImpl
            {
                Name = "_cctor_called",
                Type = new TypeImpl {
                    SpecialType = SpecialType.System_Boolean
                },
                ContainingType      = (INamedTypeSymbol)type,
                ContainingNamespace = type.ContainingNamespace,
                IsStatic            = true
            };

            unit.Declarations.Add(new CCodeFieldDeclaration(cctorCalledField)
            {
                DoNotWrapStatic = true
            });
            unit.Definitions.Add(new CCodeFieldDefinition(cctorCalledField)
            {
                DoNotWrapStatic = true
            });
        }
示例#10
0
        private static void BuildTypeHolderVariables(ITypeSymbol type, CCodeUnit unit)
        {
            // add call flag for static constructor
            var typeHolderField = new FieldImpl
            {
                Name = "__type",
                Type =
                    new NamedTypeImpl
                {
                    Name = "RuntimeType",
                    ContainingNamespace =
                        new NamespaceImpl
                    {
                        MetadataName        = "System",
                        ContainingNamespace = new NamespaceImpl {
                            IsGlobalNamespace = true, ContainingAssembly = new AssemblySymbolImpl {
                                MetadataName = "CoreLib"
                            }
                        }
                    },
                    TypeKind = TypeKind.Struct
                },
                ContainingType      = (INamedTypeSymbol)type,
                ContainingNamespace = type.ContainingNamespace,
                IsStatic            = true
            };

            unit.Declarations.Add(new CCodeFieldDeclaration(typeHolderField)
            {
                DoNotWrapStatic = true
            });
            unit.Definitions.Add(new CCodeFieldDefinition(typeHolderField)
            {
                DoNotWrapStatic = true
            });
        }
示例#11
0
        private static void BuildStaticConstructorVariables(ITypeSymbol type, CCodeUnit unit)
        {
            // add call flag for static constructor
            var cctorBeingCalledField = new FieldImpl
            {
                Name = "_cctor_being_called",
                Type = new NamedTypeImpl {
                    SpecialType = SpecialType.System_Boolean
                },
                ContainingType      = (INamedTypeSymbol)type,
                ContainingNamespace = type.ContainingNamespace,
                IsStatic            = true,
                HasConstantValue    = true,
                ConstantValue       = "false"
            };

            unit.Declarations.Add(new CCodeFieldDeclaration(cctorBeingCalledField)
            {
                DoNotWrapStatic = true
            });
            unit.Definitions.Add(new CCodeFieldDefinition(cctorBeingCalledField)
            {
                DoNotWrapStatic = true
            });

            // add call flag for static constructor
            var cctorCalledField = new FieldImpl
            {
                Name = "_cctor_called",
                Type = new NamedTypeImpl {
                    SpecialType = SpecialType.System_Boolean
                },
                ContainingType      = (INamedTypeSymbol)type,
                ContainingNamespace = type.ContainingNamespace,
                IsStatic            = true,
                HasConstantValue    = true,
                ConstantValue       = "false"
            };

            unit.Declarations.Add(new CCodeFieldDeclaration(cctorCalledField)
            {
                DoNotWrapStatic = true
            });
            unit.Definitions.Add(new CCodeFieldDefinition(cctorCalledField)
            {
                DoNotWrapStatic = true
            });

            var cctorCalledLock = new FieldImpl
            {
                Name = "_cctor_lock",
                Type = new NamedTypeImpl {
                    Name = "recursive_mutex", TypeKind = TypeKind.Struct, ContainingNamespace = new NamespaceImpl {
                        MetadataName = "std"
                    }
                },
                ContainingType      = (INamedTypeSymbol)type,
                ContainingNamespace = type.ContainingNamespace,
                IsStatic            = true
            };

            unit.Declarations.Add(new CCodeFieldDeclaration(cctorCalledLock)
            {
                DoNotWrapStatic = true
            });
            unit.Definitions.Add(new CCodeFieldDefinition(cctorCalledLock)
            {
                DoNotWrapStatic = true
            });
        }
示例#12
0
        private void WriteSource(AssemblyIdentity identity, CCodeUnit unit, bool stubs = false)
        {
            int nestedLevel;

            if (stubs)
            {
                var path = this.GetPath(unit, out nestedLevel, folder: !stubs ? "src" : "impl", doNotCreateFolder: true);
                if (File.Exists(path))
                {
                    // do not overwrite an existing file
                    return;
                }
            }

            var anyRecord = false;
            var text      = new StringBuilder();

            using (var itw = new IndentedTextWriter(new StringWriter(text)))
            {
                var c = new CCodeWriterText(itw);

                WriteSourceInclude(itw, identity);

                var namedTypeSymbol = (INamedTypeSymbol)unit.Type;
                WriteNamespaceOpen(namedTypeSymbol, itw, c);

                foreach (var definition in unit.Definitions.Where(d => !d.IsGeneric && d.IsStub == stubs))
                {
                    anyRecord = true;
                    definition.WriteTo(c);
                }

                if (!stubs)
                {
                    // write interface wrappers
                    foreach (var iface in unit.Type.Interfaces)
                    {
                        anyRecord |= WriteInterfaceWrapperImplementation(c, iface, namedTypeSymbol);
                    }
                }

                WriteNamespaceClose(namedTypeSymbol, itw);

                if (!stubs && unit.MainMethod != null)
                {
                    WriteSourceMainEntry(c, itw, unit.MainMethod);
                }

                itw.Close();
            }

            if (anyRecord && text.Length > 0)
            {
                var path    = this.GetPath(unit, out nestedLevel, folder: !stubs ? "src" : "impl");
                var newText = text.ToString();

                if (IsNothingChanged(path, newText))
                {
                    return;
                }

                using (var textFile = new StreamWriter(path))
                {
                    textFile.Write(newText);
                }
            }
        }
示例#13
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);
        }
示例#14
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);
        }
示例#15
0
        private void BuildMethod(IMethodSymbol method, CCodeUnit unit)
        {
            if (method.MethodKind == MethodKind.Ordinary && method.IsStatic && method.Name == "Main")
            {
                unit.MainMethod = method;
            }

            var key = ((MethodSymbol)method).ToKeyString();
            SourceMethodSymbol sourceMethod;
            var            sourceMethodFound = this.SourceMethodByMethodSymbol.TryGetValue(key, out sourceMethod);
            BoundStatement boundStatement;
            var            boundStatementFound = this.BoundBodyByMethodSymbol.TryGetValue(key, out boundStatement);

            if (!sourceMethodFound && !boundStatementFound && method.MethodKind == MethodKind.Constructor)
            {
                // ignore empty constructor as they should call Object.ctor() only which is empty
                unit.Declarations.Add(new CCodeMethodDeclaration(unit.Type, method));
                unit.Definitions.Add(new CCodeMethodDefinition(method));
                return;
            }

            Debug.Assert(sourceMethodFound || boundStatementFound, "MethodBodyOpt information can't be found");

            unit.Declarations.Add(new CCodeMethodDeclaration(unit.Type, method));
            var methodSymbol       = sourceMethodFound ? sourceMethod : method;
            var requiresCompletion = sourceMethod != null && sourceMethod.RequiresCompletion;

            // so in case of Delegates you need to complete methods yourself
            if (boundStatement != null && !ExcludeBodies(method))
            {
                unit.Definitions.Add(new CCodeMethodDefinition(method)
                {
                    BoundBody = boundStatement
                });
            }
            else if (requiresCompletion && methodSymbol.ContainingType.TypeKind == TypeKind.Delegate && !methodSymbol.IsAbstract)
            {
                MethodBody body;
                switch (methodSymbol.Name)
                {
                case "BeginInvoke":
                    body = MethodBodies.ReturnNull(method);
                    break;

                case "Invoke":
                    body = MethodBodies.ReturnDefault(method);
                    break;

                case "EndInvoke":
                    body = MethodBodies.ReturnDefault(method);
                    break;

                default:
                    body = MethodBodies.Throw(method);
                    break;
                }

                unit.Definitions.Add(
                    new CCodeMethodDefinition(method)
                {
                    MethodBodyOpt = body
                });
            }
            else
            {
#if GENERATE_STUBS
                if (methodSymbol.ContainingType.TypeKind != TypeKind.Interface &&
                    !methodSymbol.IsAbstract &&
                    !methodSymbol.IsExternDeclaration())
                {
                    unit.Definitions.Add(
                        new CCodeMethodDefinition(method)
                    {
                        IsStub        = true,
                        MethodBodyOpt = MethodBodies.Throw(method)
                    });
                }
#endif
            }
        }
示例#16
0
        private static void WriteFullDeclarationForUnit(CCodeUnit unit, IndentedTextWriter itw, CCodeWriterText c)
        {
            var namedTypeSymbol = (INamedTypeSymbol)unit.Type;

            WriteTemplateTraits(c, namedTypeSymbol);

            WriteNamespaceOpen(namedTypeSymbol, c);

            // write extern declaration
            var externDeclarations = unit.Declarations.Select(
                declaration => new { declaration, codeMethodDeclaration = declaration as CCodeMethodDeclaration })
                                     .Where(@t => @t.codeMethodDeclaration != null && @t.codeMethodDeclaration.IsExternDeclaration)
                                     .Select(@t => @t.declaration).ToList();

            if (externDeclarations.Any())
            {
                itw.Write("extern \"C\"");
                c.WhiteSpace();
                c.OpenBlock();

                foreach (var declaration in externDeclarations)
                {
                    declaration.WriteTo(c);
                }

                c.EndBlock();
            }

            if (namedTypeSymbol.IsGenericType)
            {
                c.WriteTemplateDeclaration(namedTypeSymbol);
            }

            itw.Write(namedTypeSymbol.IsValueType ? "struct" : "class");
            itw.Write(" ");
            c.WriteTypeName(namedTypeSymbol, false);
            if (namedTypeSymbol.BaseType != null)
            {
                itw.Write(" : public ");
                c.WriteTypeFullName(namedTypeSymbol.BaseType);
            }

            itw.WriteLine();
            itw.WriteLine("{");
            itw.WriteLine("public:");
            itw.Indent++;

            // base declaration
            if (namedTypeSymbol.BaseType != null)
            {
                itw.Write("typedef ");
                c.WriteTypeFullName(namedTypeSymbol.BaseType, false);
                itw.WriteLine(" base;");
            }

            foreach (var method in namedTypeSymbol.IterateAllMethodsWithTheSameNamesTakeOnlyOne())
            {
                c.TextSpan("using");
                c.WhiteSpace();
                c.WriteType(namedTypeSymbol.BaseType ?? method.ReceiverType, suppressReference: true, allowKeywords: true);
                c.TextSpan("::");
                c.WriteMethodName(method);
                c.TextSpan(";");
                c.NewLine();
            }

            if (namedTypeSymbol.TypeKind == TypeKind.Enum)
            {
                // value holder for enum
                c.WriteType(namedTypeSymbol);
                itw.WriteLine(" m_value;");
            }

            if (namedTypeSymbol.IsRuntimeType())
            {
                c.WriteTypeName(namedTypeSymbol, false);
                itw.WriteLine("() = default;");
            }

            /*
             * if (namedTypeSymbol.IsIntPtrType())
             * {
             *  c.WriteTypeName(namedTypeSymbol, false);
             *  itw.WriteLine("() = default;");
             * }
             */

            foreach (var declaration in unit.Declarations)
            {
                var codeMethodDeclaration = declaration as CCodeMethodDeclaration;
                if (codeMethodDeclaration == null || !codeMethodDeclaration.IsExternDeclaration)
                {
                    declaration.WriteTo(c);
                    if (codeMethodDeclaration != null && codeMethodDeclaration.MethodBodyOpt != null)
                    {
                        c.Separate();
                    }
                }
            }

            // write interface wrappers
            foreach (var iface in namedTypeSymbol.Interfaces)
            {
                WriteInterfaceWrapper(c, iface, namedTypeSymbol);
            }

            itw.Indent--;
            itw.WriteLine("};");

            WriteNamespaceClose(namedTypeSymbol, c);
        }
示例#17
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);
        }
示例#18
0
        private static void WriteFullDeclarationForUnit(CCodeUnit unit, IndentedTextWriter itw, CCodeWriterText c)
        {
            var any             = false;
            var namedTypeSymbol = (INamedTypeSymbol)unit.Type;

            foreach (var namespaceNode in namedTypeSymbol.ContainingNamespace.EnumNamespaces())
            {
                itw.Write("namespace ");
                c.WriteNamespaceName(namespaceNode);
                itw.Write(" { ");
                any = true;
            }

            if (any)
            {
                itw.Indent++;
                itw.WriteLine();
            }

            if (namedTypeSymbol.IsGenericType)
            {
                c.WriteTemplateDeclaration(namedTypeSymbol);
            }

            itw.Write(namedTypeSymbol.IsValueType ? "struct" : "class");
            itw.Write(" ");
            c.WriteTypeName(namedTypeSymbol, false);
            if (namedTypeSymbol.BaseType != null)
            {
                itw.Write(" : public ");
                c.WriteTypeFullName(namedTypeSymbol.BaseType);
            }

            itw.WriteLine();
            itw.WriteLine("{");
            itw.WriteLine("public:");
            itw.Indent++;

            // base declaration
            if (namedTypeSymbol.BaseType != null)
            {
                itw.Write("typedef ");
                c.WriteTypeFullName(namedTypeSymbol.BaseType, false);
                itw.WriteLine(" base;");
            }

            foreach (var method in namedTypeSymbol.IterateAllMethodsWithTheSameNamesTakeOnlyOne())
            {
                c.TextSpan("using");
                c.WhiteSpace();
                c.WriteType(namedTypeSymbol.BaseType ?? method.ReceiverType, suppressReference: true, allowKeywords: true);
                c.TextSpan("::");
                c.WriteMethodName(method);
                c.TextSpan(";");
                c.NewLine();
            }

            if (namedTypeSymbol.TypeKind == TypeKind.Enum)
            {
                // value holder for enum
                c.WriteType(namedTypeSymbol);
                itw.WriteLine(" m_value;");
            }

            /*
             * if (!unit.HasDefaultConstructor)
             * {
             *  c.WriteTypeName(namedTypeSymbol, false);
             *  itw.WriteLine("() = default;");
             * }
             */

            foreach (var declaration in unit.Declarations)
            {
                declaration.WriteTo(c);
            }

            // write interface wrappers
            foreach (var iface in namedTypeSymbol.Interfaces)
            {
                WriteInterfaceWrapper(c, iface, namedTypeSymbol);
            }

            itw.Indent--;
            itw.WriteLine("};");

            if (namedTypeSymbol.TypeKind == TypeKind.Delegate)
            {
                itw.WriteLine();
                new CCodeDelegateWrapperClass(namedTypeSymbol).WriteTo(c);
                itw.WriteLine();
            }

            foreach (var namespaceNode in namedTypeSymbol.ContainingNamespace.EnumNamespaces())
            {
                itw.Indent--;
                itw.Write("}");
            }

            itw.WriteLine();

            if (namedTypeSymbol.IsPrimitiveValueType() || namedTypeSymbol.TypeKind == TypeKind.Enum || namedTypeSymbol.SpecialType == SpecialType.System_Void)
            {
                // value to class
                c.TextSpanNewLine("template<>");
                c.TextSpan("struct");
                c.WhiteSpace();
                c.TextSpan("valuetype_to_class<");
                c.WriteType(namedTypeSymbol);
                c.TextSpan(">");
                c.WhiteSpace();
                c.TextSpan("{ typedef");
                c.WhiteSpace();
                c.WriteType(namedTypeSymbol, true, false, true);
                c.WhiteSpace();
                c.TextSpan("type; };");

                // class to value
                c.TextSpanNewLine("template<>");
                c.TextSpan("struct");
                c.WhiteSpace();
                c.TextSpan("class_to_valuetype<");
                c.WriteType(namedTypeSymbol, true, false, true);
                c.TextSpan(">");
                c.WhiteSpace();
                c.TextSpan("{ typedef");
                c.WhiteSpace();
                c.WriteType(namedTypeSymbol);
                c.WhiteSpace();
                c.TextSpan("type; };");

                itw.WriteLine();
                if (namedTypeSymbol.SpecialType != SpecialType.System_Void)
                {
                    new CCodeBoxForPrimitiveValuesOrEnumsDeclaration(namedTypeSymbol).WriteTo(c);
                    itw.WriteLine();
                }
            }
        }