/// <summary> /// Function that should evaluate <see cref="UserType.TypeName"/> property. /// </summary> /// <returns>User type name.</returns> protected override string GetTypeName() { string className = Symbol.Namespaces.Last(); int index = className.IndexOf('<'); if (index > 0) { className = className.Substring(0, index); } className = CodeNaming.FixUserNaming(className); if (!string.IsNullOrEmpty(ConstructorNameSuffix)) { className += ConstructorNameSuffix; } if (SpecializedRepresentative.NumberOfTemplateArguments > 0) { StringBuilder sb = new StringBuilder(); sb.Append(className); sb.Append('<'); for (int i = 0; i < SpecializedRepresentative.NumberOfTemplateArguments; i++) { sb.Append(SpecializedRepresentative.GetTemplateArgumentName(i)); sb.Append(','); sb.Append(' '); } sb.Length -= 2; sb.Append('>'); return(sb.ToString()); } return(className); }
/// <summary> /// Initializes a new instance of the <see cref="NamespaceUserType"/> class. /// </summary> /// <param name="innerNamespaces">The list of inner namespaces (e.g. chrono in std::chrono).</param> /// <param name="topLevelNamespace">The top level namespace (e.g. module name).</param> /// <param name="factory">User type factory that contains this element.</param> internal NamespaceUserType(IEnumerable <string> innerNamespaces, string topLevelNamespace, UserTypeFactory factory) : base(symbol: null, xmlType: null, nameSpace: null, factory: factory) { namespaces = innerNamespaces.Select(s => CodeNaming.FixUserNaming(s)).ToList(); if (topLevelNamespace != null) { namespaces.Insert(0, topLevelNamespace); } }
/// <summary> /// Function that should evaluate <see cref="TypeName"/> property. /// </summary> /// <returns>User type name.</returns> protected virtual string GetTypeName() { string className = Symbol.Namespaces.Last(); className = CodeNaming.FixUserNaming(className); if (!string.IsNullOrEmpty(ConstructorNameSuffix)) { className += ConstructorNameSuffix; } return(className); }
/// <summary> /// Function that should evaluate <see cref="UserType.TypeName"/> property. /// </summary> /// <returns>User type name.</returns> protected override string GetTypeName() { if (Symbol is EnumConstantSymbol enumConstant) { return(CodeNaming.FixUserNaming($"{enumConstant.EnumSymbol.UserType.FullTypeName}_{enumConstant.Value}")); } if (Symbol is IntegralConstantSymbol integralConstant) { return(CodeNaming.FixUserNaming($"{CodeNaming.ToString(integralConstant.Value.GetType())}_{integralConstant.Value}")); } throw new System.NotImplementedException(); }
/// <summary> /// Function that should evaluate <see cref="ConstructorName"/> property. /// </summary> /// <returns>User type constructor name.</returns> protected virtual string GetConstructorName() { string className = Symbol?.Namespaces?.LastOrDefault() ?? TypeName; if (this is TemplateUserType || this is SpecializedTemplateUserType) { int index = className.IndexOf('<'); if (index >= 0) { className = className.Substring(0, index); } } return(CodeNaming.FixUserNaming(className)); }
/// <summary> /// Function that should evaluate <see cref="UserType.TypeName"/> property. /// </summary> /// <returns>User type name.</returns> protected override string GetTypeName() { string className = Symbol.Namespaces.Last(); int index = className.IndexOf('<'); if (index > 0) { className = className.Substring(0, index); } className = CodeNaming.FixUserNaming(className); if (!string.IsNullOrEmpty(ConstructorNameSuffix)) { className += ConstructorNameSuffix; } if (NumberOfTemplateArguments > 0) { StringBuilder sb = new StringBuilder(); sb.Append(className); sb.Append('<'); foreach (Symbol arg in TemplateArgumentsAsSymbols) { if (arg.UserType != null) { sb.Append(arg.UserType.FullTypeName); } else { sb.Append(OriginalFactory.GetSymbolTypeInstance(this, arg).GetTypeString()); } sb.Append(','); sb.Append(' '); } sb.Length -= 2; sb.Append('>'); return(sb.ToString()); } return(className); }
/// <summary> /// Try to generate fields based on the Hungarian notation used in class fields. /// </summary> /// <param name="fixName">Function that generated unique field names with desire to keep existing name.</param> protected virtual IEnumerable <HungarianArrayUserTypeMember> GenerateHungarianNotationFields(Func <string, string> fixName) { // TODO: Add comments to this function and expand XML documentation comment const string CounterPrefix = "m_c"; const string PointerPrefix = "m_p"; const string ArrayPrefix = "m_rg"; SymbolField[] fields = Symbol.Fields; IEnumerable <SymbolField> counterFields = fields.Where(r => r.Name.StartsWith(CounterPrefix)); Dictionary <SymbolField, SymbolField> userTypesArrays = new Dictionary <SymbolField, SymbolField>(); foreach (SymbolField counterField in counterFields) { if (counterField.Type.BasicType != BasicType.UInt && counterField.Type.BasicType != BasicType.Int && counterField.Type.BasicType != BasicType.Long && counterField.Type.BasicType != BasicType.ULong) { continue; } if (counterField.Type.Tag == CodeTypeTag.Enum) { continue; } string counterNameSurfix = counterField.Name.Substring(CounterPrefix.Length); if (string.IsNullOrEmpty(counterNameSurfix)) { continue; } foreach (SymbolField pointerField in fields.Where(r => (r.Name.StartsWith(PointerPrefix) || r.Name.StartsWith(ArrayPrefix)) && r.Name.EndsWith(counterNameSurfix))) { if ((counterField.IsStatic) != (pointerField.IsStatic)) { continue; } if (pointerField.Type.Tag != CodeTypeTag.Pointer) { continue; } if (userTypesArrays.ContainsKey(pointerField)) { if (userTypesArrays[pointerField].Name.Length > counterField.Name.Length) { continue; } } userTypesArrays[pointerField] = counterField; } } foreach (var userTypeArray in userTypesArrays) { SymbolField pointerField = userTypeArray.Key; SymbolField counterField = userTypeArray.Value; TypeInstance fieldType = Factory.GetSymbolTypeInstance(this, pointerField.Type); if (fieldType is ArrayTypeInstance) { continue; } if (fieldType is PointerTypeInstance fieldTypeCodePointer) { fieldType = fieldTypeCodePointer.ElementType; } yield return(new HungarianArrayUserTypeMember() { AccessLevel = AccessLevel.Public, Name = fixName(CodeNaming.FixUserNaming(pointerField.Name + "Array")), Type = new ArrayTypeInstance(fieldType), UserType = this, PointerFieldName = pointerField.Name, CounterFieldName = counterField.Name, }); } }
/// <summary> /// Function that should evaluate <see cref="Members"/> property. /// </summary> protected virtual IEnumerable <UserTypeMember> GetMembers() { // Prepare naming "deduplication" and error fixing HashSet <string> usedNames = new HashSet <string>(); Func <string, string> fixName = (string nameBase) => { string name = nameBase; for (int i = 0; usedNames.Contains(name); i++) { if (i > 0) { name = $"{nameBase}_{i}"; } else { name = $"{nameBase}_"; } } usedNames.Add(name); return(name); }; usedNames.Add(ConstructorName); foreach (UserType innerType in InnerTypes) { usedNames.Add(innerType.ConstructorName); } // Add constants and data fields foreach (var field in Symbol.Fields) { if (field.IsStatic && !field.IsValidStatic) { continue; } if (field.IsStatic && DontExportStaticFields) { continue; } if (!field.IsStatic && ExportOnlyStaticFields) { continue; } string fieldName = fixName(CodeNaming.FixUserNaming(field.Name)); if (field.LocationType == LocationType.Constant) { yield return new ConstantUserTypeMember() { AccessLevel = AccessLevel.Public, Name = fieldName, Type = Factory.GetSymbolTypeInstance(this, field.Type, field.BitSize), Symbol = field, UserType = this, } } ; else { yield return new DataFieldUserTypeMember() { AccessLevel = AccessLevel.Public, Name = fieldName, Type = Factory.GetSymbolTypeInstance(this, field.Type, field.BitSize), Symbol = field, UserType = this, } }; } // Hungarian notation fields if (!ExportOnlyStaticFields) { foreach (UserTypeMember member in GenerateHungarianNotationFields(fixName)) { yield return(member); } } // Base class properties if (!ExportOnlyStaticFields && (BaseClass is MultiClassInheritanceTypeInstance || BaseClass is SingleClassInheritanceWithInterfacesTypeInstance)) { Symbol[] baseClasses = Symbol.BaseClasses; Symbol[] baseClassesForProperties = BaseClass is SingleClassInheritanceWithInterfacesTypeInstance?baseClasses.Where(b => b.IsEmpty).ToArray() : baseClasses; List <Symbol> baseClassesSorted = baseClasses.OrderBy(s => s.Offset).ThenBy(s => s.Name).ToList(); foreach (Symbol baseClass in baseClassesForProperties) { // Generate simplified base class name TypeInstance type = Factory.GetSymbolTypeInstance(this, baseClass); string baseClassName = CodeNaming.FixUserNaming(type.GetTypeString(truncateNamespace: true)); StringBuilder sb = new StringBuilder(); int i = baseClassName[0] == '@' ? 1 : 0; for (; i < baseClassName.Length; i++) { switch (baseClassName[i]) { case '_': case '.': if (i > 0 && baseClassName[i - 1] != '_') { sb.Append('_'); } break; default: sb.Append(baseClassName[i]); break; } } while (sb.Length > 0 && sb[sb.Length - 1] == '_') { sb.Length--; } baseClassName = sb.ToString(); // Create property string propertyName = fixName(baseClassesForProperties.Length > 1 ? $"BaseClass_{baseClassName}" : "BaseClass"); yield return(new BaseClassPropertyUserTypeMember() { AccessLevel = AccessLevel.Public, Name = propertyName, Type = type, Symbol = baseClass, UserType = this, Index = baseClassesSorted.IndexOf(baseClass), }); } } }
/// <summary> /// Function that should evaluate <see cref="Namespace"/> property. /// </summary> /// <param name="constructorNamespace">Namespace parameter of the constructor of this class.</param> protected virtual string GetNamespace(string constructorNamespace) { return(CodeNaming.FixUserNaming(constructorNamespace)); }