private TypeTree FixTypeTree(TypeTree typeTree, Symbol type, UserTypeFactory factory) { // Check basic type BasicTypeTree basicTypeTree = typeTree as BasicTypeTree; if (basicTypeTree != null) { // Basic type tree is not challenged against template arguments, so try to do that. UserType basicUserType; if (CreateFactory(factory).GetUserType(type, out basicUserType)) { TypeTree tree = UserTypeTree.Create(basicUserType, factory); if (tree != null) { return(tree); } } // Failed to match the type // TODO: Look for typedeclared. Class is using different types than in template specialization. We cannot support it right now. return(new VariableTypeTree()); } // Check array type ArrayTypeTree arrayTypeTree = typeTree as ArrayTypeTree; if (arrayTypeTree != null) { TypeTree elementTypeTree = FixTypeTree(arrayTypeTree.ElementType, type.ElementType, factory); if (elementTypeTree != arrayTypeTree.ElementType) { return(new ArrayTypeTree(elementTypeTree)); } return(arrayTypeTree); } // Check pointer type PointerTypeTree pointerTypeTree = typeTree as PointerTypeTree; if (pointerTypeTree != null) { TypeTree elementTypeTree = FixTypeTree(pointerTypeTree.ElementType, type.ElementType, factory); if (elementTypeTree != pointerTypeTree.ElementType) { return(new PointerTypeTree(elementTypeTree)); } return(pointerTypeTree); } return(typeTree); }
/// <summary> /// Gets the type tree for the specified field. /// </summary> /// <param name="field">The field.</param> /// <param name="factory">The user type factory.</param> /// <param name="extractingBaseClass">if set to <c>true</c> user type field is being generated for getting base class.</param> /// <param name="bitLength">Number of bits used for this symbol.</param> protected override TypeTree GetFieldTypeTree(SymbolField field, UserTypeFactory factory, bool extractingBaseClass, int bitLength = 0) { // Do not match specializations when getting type for base class. if (extractingBaseClass || NumberOfTemplateArguments == 0) { return(GetSymbolTypeTree(field.Type, factory, bitLength)); } // Check field in all specializations var specializedFields = SpecializedTypes.Select(r => new Tuple <TemplateUserType, SymbolField>(r, r.Symbol.Fields.FirstOrDefault(q => q.Name == field.Name))).ToArray(); if (specializedFields.Any(r => r.Item2 == null)) { // TODO: Incorrect bucketization. Field does not exist in all specialization. return(GetSymbolTypeTree(field.Type, factory, bitLength)); } if (specializedFields.All(r => r.Item2.Type.Name == field.Type.Name)) { // There is no specialization, all types across the specializations are the same. return(GetSymbolTypeTree(field.Type, factory, bitLength)); } // Try to get type tree TypeTree result = GetSymbolTypeTree(field.Type, factory, bitLength); if (result is BasicTypeTree) { // Basic type tree is not challenged against template arguments, so try to do that. UserType basicUserType; if (CreateFactory(factory).GetUserType(field.Type, out basicUserType)) { TypeTree tree = UserTypeTree.Create(basicUserType, factory); if (tree != null) { return(tree); } } // Failed to match the type // TODO: Look for typedeclared. Class is using different types than in template specialization. We cannot support it right now. return(new VariableTypeTree()); } 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); }