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 }); } }
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 }); }
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()))); }
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 }); }
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); }
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 }); } }
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(";"); } }
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 }); }
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 }); }
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 }); }
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 }); }
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); } } }
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); }
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); }
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 } }
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); }
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); }
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(); } } }