/// <summary> /// Initializes a new instance of the <see cref="UserTypeTransformation"/> class. /// </summary> /// <param name="transformation">The XML transformation definition.</param> /// <param name="typeConverter">The type converter.</param> /// <param name="ownerUserType">The owner user type.</param> /// <param name="type">The type that should be transformed to user type.</param> public UserTypeTransformation(XmlTypeTransformation transformation, Func<string, string> typeConverter, UserType ownerUserType, Symbol type) { Transformation = transformation; this.typeConverter = typeConverter; this.ownerUserType = ownerUserType; this.type = type; }
/// <summary> /// Initializes a new instance of the <see cref="UserTypeTransformation"/> class. /// </summary> /// <param name="transformation">The XML transformation definition.</param> /// <param name="typeConverter">The type converter.</param> /// <param name="ownerUserType">The owner user type.</param> /// <param name="type">The type that should be transformed to user type.</param> public UserTypeTransformation(XmlTypeTransformation transformation, Func <string, string> typeConverter, UserType ownerUserType, Symbol type) { Transformation = transformation; this.typeConverter = typeConverter; this.ownerUserType = ownerUserType; this.type = type; }
/// <summary> /// Initializes a new instance of the <see cref="UserTypeTransformation"/> class. /// </summary> /// <param name="transformation">The XML transformation definition.</param> /// <param name="typeConverter">The type converter.</param> /// <param name="ownerUserType">The owner user type.</param> /// <param name="type">The type that should be transformed to user type.</param> public UserTypeTransformation(XmlTypeTransformation transformation, Func <string, string> typeConverter, UserType ownerUserType, Symbol type) { Transformation = transformation; this.typeConverter = typeConverter; this.ownerUserType = ownerUserType; this.type = type; typeStringCache = SimpleCache.CreateStruct(() => Transformation.TransformType(type.Name, typeConverter)); }
/// <summary> /// Tries to match transformation for the specified type. /// </summary> /// <param name="type">The type.</param> /// <param name="ownerUserType">The owner user type.</param> /// <returns>Transformation if matched one is found; otherwise null.</returns> internal UserTypeTransformation FindTransformation(Symbol type, UserType ownerUserType) { // Check if we have any transformation if (typeTransformations.Length == 0) { return(null); } // Find first transformation that matches the specified type string originalFieldTypeString = type.Name; XmlTypeTransformation transformation = typeTransformations.FirstOrDefault(t => t.Matches(originalFieldTypeString)); if (transformation == null) { return(null); } // Create type converter function for the transformation Func <string, string> typeConverter = null; typeConverter = (inputType) => { XmlTypeTransformation tr = typeTransformations.FirstOrDefault(t => t.Matches(inputType)); if (tr != null) { return(tr.TransformType(inputType, typeConverter)); } UserType userType; if (GetUserType(type.Module, inputType, out userType)) { return(ownerUserType.Factory.GetSymbolTypeInstance(ownerUserType, userType.Symbol).GetTypeString()); } Symbol symbol = type.Module.GetSymbol(inputType); if (symbol != null) { if ((symbol.Tag == CodeTypeTag.BuiltinType) || (symbol.Tag == CodeTypeTag.Pointer && symbol.ElementType.Tag == CodeTypeTag.BuiltinType) || (symbol.Tag == CodeTypeTag.Array && symbol.ElementType.Tag == CodeTypeTag.BuiltinType)) { return(ownerUserType.Factory.GetSymbolTypeInstance(ownerUserType, symbol).GetTypeString()); } } return(new VariableTypeInstance(CodeNaming).GetTypeString()); }; return(new UserTypeTransformation(transformation, typeConverter, ownerUserType, type)); }
/// <summary> /// Parses template arguments for the specified symbol name. /// </summary> /// <param name="module">Module that contains this symbol.</param> /// <param name="symbolName">The symbol name.</param> /// <param name="result">List of symbols that will contain parsed template arguments.</param> /// <returns><c>true</c> if all template arguments were parsed correctly and found in the global cache.</returns> internal static bool ParseTemplateArguments(SymbolProviders.Module module, string symbolName, List <Symbol> result) { int templateStart = symbolName.IndexOf('<'); if (templateStart > 0) { // Parse template arguments List <string> arguments = new List <string>(); for (int i = templateStart + 1; i < symbolName.Length && symbolName[i] != '>'; i++) { string originalyExtractedType = XmlTypeTransformation.ExtractType(symbolName, i); string extractedType = originalyExtractedType.Trim(); i += originalyExtractedType.Length; if (string.IsNullOrEmpty(extractedType)) { // This can happen only when list is empty if (arguments.Count > 0) { throw new NotImplementedException("Unexpected empty template argument in symbol " + symbolName); } break; } arguments.Add(extractedType); // Try to see if argument is constant if (module.IsConstant(extractedType)) { // Create constant symbol for this string result.Add(module.GetConstantSymbol(extractedType)); } else { // Check if type is existing type (symbol) Symbol symbol = GlobalCache.GetSymbol(extractedType, module); if (symbol == null) { // TODO: Check if this is unused argument and we should ignore it. return(false); } result.Add(symbol); } } } return(true); }
private static IEnumerable <Symbol> ParseTemplateArguments(UserTypeFactory factory, Module module, string symbolName) { int templateStart = symbolName.IndexOf('<'); if (templateStart > 0) { // Parse template arguments List <string> arguments = new List <string>(); for (int i = templateStart + 1; i < symbolName.Length && symbolName[i] != '>'; i++) { string originalyExtractedType = XmlTypeTransformation.ExtractType(symbolName, i); string extractedType = originalyExtractedType.Trim(); i += originalyExtractedType.Length; if (string.IsNullOrEmpty(extractedType)) { // This can happen only when list is empty if (arguments.Count > 0) { throw new NotImplementedException("Unexpected empty template argument in symbol " + symbolName); } break; } arguments.Add(extractedType); // Try to see if argument is number (constants are removed from the template arguments as they cannot be used in C#) double constant; if (!double.TryParse(extractedType, out constant)) { // Check if type is existing type (symbol) Symbol symbol = GlobalCache.GetSymbol(extractedType, module); if (symbol == null) { throw new Exception("Wrongly formed template argument"); } yield return(symbol); } } } }
/// <summary> /// Initializes a new instance of the <see cref="UserTypeFactory"/> class. /// </summary> /// <param name="transformations">The transformations.</param> public UserTypeFactory(XmlTypeTransformation[] transformations) { typeTransformations = transformations; }
/// <summary> /// Updates the template arguments (symbols and user types). /// </summary> /// <param name="factory">The user type factory.</param> /// <returns><c>true</c> if all template arguments are resolved as user types.</returns> public bool UpdateTemplateArguments(UserTypeFactory factory) { string symbolName = Symbol.Namespaces.Last(); int templateStart = symbolName.IndexOf('<'); bool result = true; templateArgumentsAsSymbols.Clear(); templateArgumentsAsUserTypes.Clear(); if (templateStart > 0) { // Parse template arguments List <string> arguments = new List <string>(); for (int i = templateStart + 1; i < symbolName.Length && symbolName[i] != '>'; i++) { string originalyExtractedType = XmlTypeTransformation.ExtractType(symbolName, i); string extractedType = originalyExtractedType.Trim(); i += originalyExtractedType.Length; if (string.IsNullOrEmpty(extractedType)) { // This can happen only when list is empty if (arguments.Count > 0) { throw new NotImplementedException("Unexpected empty template argument in symbol " + symbolName); } break; } arguments.Add(extractedType); // Try to see if argument is number (constants are removed from the template arguments as they cannot be used in C#) double constant; if (!double.TryParse(extractedType, out constant)) { // Check if type is existing type (symbol) Symbol symbol = GlobalCache.GetSymbol(extractedType, Module); if (symbol == null) { throw new Exception("Wrongly formed template argument"); } templateArgumentsAsSymbols.Add(symbol); // Try to get user type for the symbol UserType specializationUserType = null; if (!factory.GetUserType(symbol, out specializationUserType)) { if (symbol.Tag != Dia2Lib.SymTagEnum.SymTagEnum && symbol.Tag != Dia2Lib.SymTagEnum.SymTagUDT) { var typeString = GetSymbolTypeTree(symbol, factory).GetTypeString(); specializationUserType = new TemplateArgumentUserType(typeString, symbol); } } templateArgumentsAsUserTypes.Add(specializationUserType); result = result && specializationUserType != null; } } } // TODO: Unused types should be removed return(result); }