protected override void BuildTypedef(CodeNamespace ns, CppTypedef typedef) { TypeDesc fieldType = GetTypeDesc(typedef.ElementType); string baseTypeName = ResolveCefType(fieldType.ToString()); string aliasTypeName = GetClassName(typedef.Name); if (aliasTypeName == baseTypeName) { throw new InvalidOperationException(); } var decl = new CodeStruct(aliasTypeName); decl.Attributes = CodeAttributes.Public | CodeAttributes.Unsafe | CodeAttributes.Partial; decl.Comments.AddVSDocComment(typedef.Comment, "summary"); var attr = new CustomCodeAttribute(typeof(StructLayoutAttribute)); attr.AddParameter(LayoutKind.Sequential); decl.CustomAttributes.Add(attr); var field = new CodeField(baseTypeName, "Base"); field.Attributes = CodeAttributes.Public; //field.CustomAttributes.Add(new CustomCodeAttribute(typeof(FieldOffsetAttribute)) { Parameters = { "0" } }); decl.Members.Add(field); ns.Types.Add(decl); }
public static bool IsFunctionType(this CppTypedef typedef) { // search the ElementType hiearchy for CppTypedefs and CppPointers until we finally get to a CppFunction or not if (typedef.ElementType is CppTypedef td) { return(td.IsFunctionType()); } if (typedef.ElementType is CppPointerType ptr) { if (ptr.ElementType.TypeKind == CppTypeKind.Function) { return(true); } } if (typedef.ElementType.TypeKind == CppTypeKind.Function) { return(true); } return(false); }
public void TestNamespacedTypedef() { ParseAssert(@" namespace A { typedef int (*a)(int b); } A::a c; ", compilation => { Assert.False(compilation.HasErrors); Assert.AreEqual(1, compilation.Namespaces.Count); ICppGlobalDeclarationContainer container = compilation.Namespaces[0]; Assert.AreEqual(1, container.Typedefs.Count); Assert.AreEqual(1, compilation.Fields.Count); CppTypedef typedef = container.Typedefs[0]; CppField field = compilation.Fields[0]; Assert.AreEqual(typedef, field.Type); } ); }
private CSharpElement ConvertTypedef(CSharpConverter converter, CppTypedef cppTypedef, CSharpElement context) { var elementType = cppTypedef.ElementType; if (DefaultFunctionTypeConverter.IsFunctionType(elementType, out var cppFunctionType)) { return(DefaultFunctionTypeConverter.ConvertNamedFunctionType(converter, cppFunctionType, context, cppTypedef)); } var isFromSystemIncludes = converter.IsFromSystemIncludes(cppTypedef); var csElementType = converter.GetCSharpType(elementType, context, true); var noWrap = converter.Options.TypedefCodeGenKind == CppTypedefCodeGenKind.NoWrap && !converter.Options.TypedefWrapWhiteList.Contains(cppTypedef.Name); // If: // - the typedef is from system includes and the underlying type is not a pointer // - or the typedef mode is "no-wrap" and is not in the whitelist // then we bypass entirely the typedef and return immediately the element type bool is_size_t = isFromSystemIncludes && cppTypedef.Name == "size_t"; if (noWrap || (isFromSystemIncludes && elementType.TypeKind != CppTypeKind.Pointer && !is_size_t)) { return(csElementType); } // Otherwise we generate a small wrapper struct var csStructName = converter.GetCSharpName(cppTypedef, context); var csStruct = new CSharpStruct(csStructName) { CppElement = cppTypedef, }; var container = converter.GetCSharpContainer(cppTypedef, context); converter.ApplyDefaultVisibility(csStruct, container); container.Members.Add(csStruct); csStruct.Comment = converter.GetCSharpComment(cppTypedef, csStruct); // Requires System.Runtime.InteropServices csStruct.Attributes.Add(new CSharpStructLayoutAttribute(LayoutKind.Sequential) { CharSet = converter.Options.DefaultCharSet }); // Required by StructLayout converter.AddUsing(container, "System.Runtime.InteropServices"); var name = csStruct.Name; csStruct.Modifiers |= CSharpModifiers.ReadOnly; csStruct.BaseTypes.Add(new CSharpFreeType($"IEquatable<{name}>")); // Dump the type name and attached attributes for the element type var attachedAttributes = string.Empty; var csElementTypeName = is_size_t ? "IntPtr" : converter.ConvertTypeReferenceToString(csElementType, out attachedAttributes); csStruct.Members.Add(new CSharpLineElement($"public {name}({csElementTypeName} value) => this.Value = value;")); csStruct.Members.Add(new CSharpLineElement($"{attachedAttributes}public readonly {csElementTypeName} Value;")); csStruct.Members.Add(new CSharpLineElement($"public bool Equals({name} other) => Value.Equals(other.Value);")); csStruct.Members.Add(new CSharpLineElement($"public override bool Equals(object obj) => obj is {name} other && Equals(other);")); csStruct.Members.Add(new CSharpLineElement($"public override int GetHashCode() => Value.GetHashCode();")); csStruct.Members.Add(new CSharpLineElement($"public override string ToString() => Value.ToString();")); csStruct.Members.Add(new CSharpLineElement($"public static implicit operator {csElementTypeName}({name} from) => from.Value;")); csStruct.Members.Add(new CSharpLineElement($"public static implicit operator {name}({csElementTypeName} from) => new {name}(from);")); csStruct.Members.Add(new CSharpLineElement($"public static bool operator ==({name} left, {name} right) => left.Equals(right);")); csStruct.Members.Add(new CSharpLineElement($"public static bool operator !=({name} left, {name} right) => !left.Equals(right);")); return(csStruct); }
protected abstract void BuildTypedef(CodeNamespace ns, CppTypedef typedef);
private GenerateResult GenerateTypedef(CppTypedef cppTypedef) { var elementType = cppTypedef.ElementType; var array = false; if (elementType is CppPointerType pointerType) { array = true; elementType = pointerType.ElementType; } if (elementType.TypeKind != CppTypeKind.StructOrClass) { throw new NotSupportedException(elementType.GetDisplayName()); } var csElementType = ConvertToCSharpType(elementType); var usingDirectives = new List <UsingDirectiveSyntax>(); var csClass = new ClassDeclarationSyntax { Modifiers = Modifiers.Internal, Identifier = cppTypedef.Name }; if (array) { if (_config.NodeTypes.Contains(csClass.Identifier)) { AddPgNodeAttribute(usingDirectives, csClass); usingDirectives.Add(Syntax.UsingDirective("System.Collections.Generic")); csClass.BaseList = new BaseListSyntax { Types = { Syntax.ParseName($"List<{csElementType}>"), Syntax.ParseName(nodeInterfaceName) } }; } AddPgNodeTypeProperty(csClass, Modifiers.None); } else { csClass.BaseList = new BaseListSyntax { Types = { Syntax.ParseName(csElementType) } }; AddPgNodeAttribute(usingDirectives, csClass); AddPgNodeTypeProperty(csClass, _config.NodeTypes.Contains(csElementType) ? Modifiers.Override : Modifiers.None); } _typeMap[cppTypedef.Name] = cppTypedef.Name; return(new GenerateResult(cppTypedef) { UsingDirectives = usingDirectives.ToArray(), Type = csClass }); }
public static CppPrimitiveType ElementTypeAsPrimitive(this CppTypedef typedef) => typedef.ElementType as CppPrimitiveType;
public static bool IsPrimitiveType(this CppTypedef typedef) => typedef.ElementType.TypeKind == CppTypeKind.Primitive;
private async Task ProcessAsync(CppTypedef item) { await _handleBuilder.BuildAsync(new[] { item }); await _delegateBuilder.BuildAsync(new[] { item }); }