/// <summary> /// Look up for user type based on the specified module and type string. /// </summary> /// <param name="module">The module.</param> /// <param name="typeString">The type string.</param> /// <param name="userType">The found user type.</param> /// <returns><c>true</c> if user type was found.</returns> internal override bool GetUserType(SymbolProviders.Module module, string typeString, out UserType userType) { string argumentName; if (TryGetTemplateArgument(typeString, out argumentName)) { // TODO: #fixme investigate this userType = new TemplateArgumentUserType(argumentName, null); return(true); } return(base.GetUserType(module, typeString, out userType)); }
/// <summary> /// Look up for user type based on the specified symbol. /// </summary> /// <param name="type">The symbol.</param> /// <param name="userType">The found user type.</param> /// <returns><c>true</c> if user type was found.</returns> internal override bool GetUserType(Symbol type, out UserType userType) { string argumentName; string typeString = type.Name; if (TryGetTemplateArgument(typeString, out argumentName)) { // TODO: #fixme investigate this userType = new TemplateArgumentUserType(argumentName, type); return(true); } return(base.GetUserType(type, out userType)); }
/// <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) { bool result = true; templateArgumentsAsSymbols = ParseTemplateArguments(factory, Module, Symbol.Namespaces.Last()).ToList(); templateArgumentsAsUserTypes.Clear(); foreach (Symbol symbol in templateArgumentsAsSymbols) { // Try to get user type for the symbol UserType specializationUserType = null; if (!factory.GetUserType(symbol, out specializationUserType)) { if (symbol.Tag != CodeTypeTag.Enum && symbol.Tag != CodeTypeTag.Class && symbol.Tag != CodeTypeTag.Structure && symbol.Tag != CodeTypeTag.Union) { try { var typeString = GetSymbolTypeTree(symbol, factory).GetTypeString(); specializationUserType = new TemplateArgumentUserType(typeString, symbol); } catch { } } } templateArgumentsAsUserTypes.Add(specializationUserType); result = result && specializationUserType != null; } // Enumerate all template arguments as strings IEnumerable <Symbol> allTemplateArguments = Enumerable.Empty <Symbol>(); foreach (string symbolName in Symbol.Namespaces) { allTemplateArguments = allTemplateArguments.Concat(ParseTemplateArguments(factory, Module, symbolName)); } AllTemplateArguments = allTemplateArguments.Select(s => s.Name).ToList(); // TODO: Unused types should be removed return(result); }
/// <summary> /// Gets the type tree for the base class. /// If class has multi inheritance, it can return MultiClassInheritanceTypeTree or SingleClassInheritanceWithInterfacesTypeTree. /// </summary> /// <param name="error">The error text writer.</param> /// <param name="type">The type for which we are getting base class.</param> /// <param name="factory">The user type factory.</param> /// <param name="baseClassOffset">The base class offset.</param> protected override TypeTree GetBaseClassTypeTree(TextWriter error, Symbol type, UserTypeFactory factory, out int baseClassOffset) { TypeTree baseType = base.GetBaseClassTypeTree(error, type, CreateFactory(factory), out baseClassOffset); // Check if base type is template argument. It if is, export it as if it is multi class inheritance. UserTypeTree userBaseType = baseType as UserTypeTree; TemplateArgumentUserType primitiveUserType = userBaseType != null ? userBaseType.UserType as TemplateArgumentUserType : null; if (userBaseType != null && primitiveUserType != null) { var dict = GetGenericTypeConstraintsDictionary(factory); string commonBaseClass; if (dict.TryGetValue(primitiveUserType.ClassName, out commonBaseClass)) { return(UserTypeTree.Create(new TemplateArgumentUserType(commonBaseClass, null), factory)); } baseClassOffset = 0; return(new MultiClassInheritanceTypeTree()); } return(baseType); }
/// <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) { bool result = true; templateArgumentsAsSymbols = ParseTemplateArguments(factory, Module, Symbol.Namespaces.Last()).ToList(); templateArgumentsAsUserTypes.Clear(); foreach (Symbol symbol in templateArgumentsAsSymbols) { // 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; } // Enumerate all template arguments as strings IEnumerable<Symbol> allTemplateArguments = Enumerable.Empty<Symbol>(); foreach (string symbolName in Symbol.Namespaces) { allTemplateArguments = allTemplateArguments.Concat(ParseTemplateArguments(factory, Module, symbolName)); } AllTemplateArguments = allTemplateArguments.Select(s => s.Name).ToList(); // TODO: Unused types should be removed return result; }
/// <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); }