Ejemplo n.º 1
0
        private static IMethodSymbol GetContractClassMethod(ITypeSymbol contractClassType, IMethodSymbol baseTypeMethod)
        {
            if (baseTypeMethod.ContainingType.TypeKind == TypeKind.Interface)
            {
                if (contractClassType is INamedTypeSymbol namedcontractClassType && namedcontractClassType.IsGenericType)
                {
                    if (baseTypeMethod.ContainingType is INamedTypeSymbol baseNamed && baseNamed.IsGenericType)
                    {
                        var constructed = baseNamed.ConstructedFrom.Construct(namedcontractClassType.TypeArguments.ToArray());
                        baseTypeMethod = constructed.GetMembers().OfType <IMethodSymbol>().First(o => o.OriginalDefinition.Equals(baseTypeMethod.OriginalDefinition));
                    }

                    return(contractClassType.FindImplementationForInterfaceMember(baseTypeMethod) as IMethodSymbol);
                }

                return(contractClassType.FindImplementationForInterfaceMember(baseTypeMethod) as IMethodSymbol);
            }
            else if (baseTypeMethod.ContainingType.TypeKind == TypeKind.Class)
            {
                if (contractClassType is INamedTypeSymbol namedcontractClassType && namedcontractClassType.IsGenericType)
                {
                    return(contractClassType.GetMembers().OfType <IMethodSymbol>().FirstOrDefault(o => o.IsOverride && o.OverriddenMethod.OriginalDefinition.Equals(baseTypeMethod.OriginalDefinition)));
                }

                return(contractClassType.GetMembers().OfType <IMethodSymbol>().FirstOrDefault(o => o.IsOverride && o.OverriddenMethod.Equals(baseTypeMethod)));
            }

            return(null);
        }
        /// <summary>
        ///   Checks whether the <paramref name="symbol" />'s implementing member for <paramref name="interfaceMember" /> has the
        ///   correct port kind.
        /// </summary>
        /// <param name="context">The context in which the analysis should be performed.</param>
        /// <param name="symbol">The symbol that should be analyzed.</param>
        /// <param name="compilation">The compilation the symbol is declared in.</param>
        /// <param name="interfaceMember">The interface member that should be checked.</param>
        private static void CheckMember(SymbolAnalysisContext context, ITypeSymbol symbol, Compilation compilation, ISymbol interfaceMember)
        {
            var implementingMember = symbol.FindImplementationForInterfaceMember(interfaceMember);

            var interfaceIsRequired = interfaceMember.HasAttribute <RequiredAttribute>(compilation);
            var interfaceIsProvided = interfaceMember.HasAttribute <ProvidedAttribute>(compilation);

            var implementationIsRequired = implementingMember.HasAttribute <RequiredAttribute>(compilation) || implementingMember.IsExtern;
            var implementationIsProvided = implementingMember.HasAttribute <ProvidedAttribute>(compilation) || !implementingMember.IsExtern;

            // If we can't uniquely classify the port kind of either the interface member or the implementation,
            // there is another problem that another analyzer deals with. So let's just ignore it here.
            if ((interfaceIsRequired && interfaceIsProvided) || (implementationIsProvided && implementationIsRequired))
            {
                return;
            }

            var location = implementingMember.ContainingType.Equals(symbol) ? implementingMember : symbol;

            if (interfaceIsRequired && !implementationIsRequired)
            {
                _requiredPortImplementedAsProvidedPort.Emit(context, location,
                                                            implementingMember.ToDisplayString(), interfaceMember.ToDisplayString());
            }

            if (interfaceIsProvided && !implementationIsProvided)
            {
                _providedPortImplementedAsRequiredPort.Emit(context, location,
                                                            implementingMember.ToDisplayString(), interfaceMember.ToDisplayString());
            }
        }
Ejemplo n.º 3
0
        public static ImmutableArray <IMethodSymbol> GetImplementedMethods(
            this IMethodSymbol method
            )
        {
            if (method.ExplicitInterfaceImplementations.Length > 0)
            {
                return(method.ExplicitInterfaceImplementations);
            }

            ITypeSymbol type = method.ContainingType;

            var result = ImmutableArray.CreateBuilder <IMethodSymbol>();

            result.AddRange(
                type.AllInterfaces
                .SelectMany(i => i.GetMembers(method.Name).OfType <IMethodSymbol>())
                .Where(m => method.Equals(type.FindImplementationForInterfaceMember(m), SymbolEqualityComparer.Default))
                );;

            // Check OverriddenMethod != null instead of IsOverride
            // because "override void Foo() {}" will have IsOverride == true
            // even if there isn't a Foo to override
            if (method.OverriddenMethod != null)
            {
                result.Add(method.OverriddenMethod);
            }

            return(result.ToImmutable());
        }
Ejemplo n.º 4
0
 internal static void GenerateMissingEvents(ClassDeclarationSyntax classDeclaration, ITypeSymbol interfaceType,
                                            ITypeSymbol classType, DocumentEditor editor, SyntaxGenerator gen)
 {
     foreach (var eventSymbol in interfaceType.GetMembers().
              OfType <IEventSymbol>())
     {
         if (classType.FindImplementationForInterfaceMember(eventSymbol) != null)
         {
             continue;
         }
         editor.AddMember(classDeclaration, GenerateEvent(gen, eventSymbol));
     }
 }
        private static bool CanRefactor(
            TypeSyntax type,
            ExpressionSyntax expression,
            ExpressionSyntax accessedExpression,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(type, cancellationToken);

            if (typeSymbol?.IsErrorType() == false)
            {
                ITypeSymbol expressionTypeSymbol = semanticModel.GetTypeSymbol(expression, cancellationToken);

                if (expressionTypeSymbol?.IsErrorType() == false &&
                    !expressionTypeSymbol.IsInterface())
                {
                    bool isInterface = typeSymbol.IsInterface();

                    if (isInterface ||
                        typeSymbol.EqualsOrInheritsFrom(expressionTypeSymbol, includeInterfaces: true))
                    {
                        ISymbol accessedSymbol = semanticModel.GetSymbol(accessedExpression, cancellationToken);

                        INamedTypeSymbol containingType = accessedSymbol?.ContainingType;

                        if (containingType != null)
                        {
                            if (isInterface)
                            {
                                ISymbol implementation = expressionTypeSymbol.FindImplementationForInterfaceMember(accessedSymbol);

                                switch (implementation?.Kind)
                                {
                                case SymbolKind.Property:
                                    return(!((IPropertySymbol)implementation).ExplicitInterfaceImplementations.Any(f => f.Equals(accessedSymbol)));

                                case SymbolKind.Method:
                                    return(!((IMethodSymbol)implementation).ExplicitInterfaceImplementations.Any(f => f.Equals(accessedSymbol)));
                                }
                            }
                            else
                            {
                                return(expressionTypeSymbol.EqualsOrInheritsFrom(containingType, includeInterfaces: true));
                            }
                        }
                    }
                }
            }

            return(false);
        }
Ejemplo n.º 6
0
 internal static void GenerateMissingProperties(ClassDeclarationSyntax classDeclaration,
                                                ITypeSymbol interfaceType, ITypeSymbol classType,
                                                DocumentEditor editor, SyntaxGenerator gen)
 {
     foreach (var propertySymbol in interfaceType.GetMembers().
              OfType <IPropertySymbol>())
     {
         if (classType.FindImplementationForInterfaceMember(propertySymbol) != null)
         {
             continue;
         }
         editor.AddMember(classDeclaration,
                          GenerateProperty(gen, propertySymbol, Constants.ImplementationFieldName));
     }
 }
Ejemplo n.º 7
0
    public static bool IsMemberImplemented(this ITypeSymbol @this, ISymbol member)
    {
        ISymbol?implementation = @this.FindImplementationForInterfaceMember(member);

        if (implementation is null || implementation.IsStatic || !implementation.ContainingType.Equals(@this, SymbolEqualityComparer.Default))
        {
            return(false);
        }

        return(implementation switch
        {
            IMethodSymbol methodImplementation => methodImplementation.MethodKind == MethodKind.ExplicitInterfaceImplementation,
            IPropertySymbol propertyImplementation => propertyImplementation.ExplicitInterfaceImplementations.Any(),
            IEventSymbol eventImplementation => eventImplementation.ExplicitInterfaceImplementations.Any(),
            _ => false,
        });
Ejemplo n.º 8
0
        public static IMethodSymbol GetInterfaceImplementation(this ITypeSymbol type, IMethodSymbol interfaceMethod)
        {
            if (SymbolEqualityComparer.Default.Equals(type, interfaceMethod.ContainingType))
            {
                return(interfaceMethod);
            }

            var result = type.FindImplementationForInterfaceMember(interfaceMethod);

            if (result == null)
            {
                throw new ArgumentNullException(nameof(interfaceMethod));
            }

            return((IMethodSymbol)result);
        }
        private static bool IsExplicitlyImplemented(
            ITypeSymbol classOrStructType,
            ISymbol member,
            out ISymbol typeMember)
        {
            if (member != null && member.ContainingType.IsInterfaceType())
            {
                typeMember = classOrStructType?.FindImplementationForInterfaceMember(member);
                return(typeMember is IPropertySymbol property &&
                       property.ExplicitInterfaceImplementations.Length > 0 &&
                       property.DeclaredAccessibility == Accessibility.Private);
            }

            typeMember = member;
            return(false);
        }
Ejemplo n.º 10
0
        private static bool CheckExplicitImplementation(ITypeSymbol typeSymbol, ISymbol symbol)
        {
            ISymbol implementation = typeSymbol.FindImplementationForInterfaceMember(symbol);

            if (implementation == null)
            {
                return(false);
            }

            switch (implementation.Kind)
            {
            case SymbolKind.Property:
            {
                foreach (IPropertySymbol propertySymbol in ((IPropertySymbol)implementation).ExplicitInterfaceImplementations)
                {
                    if (propertySymbol.Equals(symbol))
                    {
                        return(false);
                    }
                }

                break;
            }

            case SymbolKind.Method:
            {
                foreach (IMethodSymbol methodSymbol in ((IMethodSymbol)implementation).ExplicitInterfaceImplementations)
                {
                    if (methodSymbol.Equals(symbol))
                    {
                        return(false);
                    }
                }

                break;
            }

            default:
            {
                Debug.Fail(implementation.Kind.ToString());
                return(false);
            }
            }

            return(true);
        }
Ejemplo n.º 11
0
        internal static void GenerateMissingMethods(ClassDeclarationSyntax classDeclaration, ITypeSymbol interfaceType,
                                                    ITypeSymbol classType, DocumentEditor editor, SyntaxGenerator gen,
                                                    SemanticModel model, int minificationLocation, bool includeAsyncAwait)
        {
            foreach (var member in interfaceType.GetMembers().
                     OfType <IMethodSymbol>().
                     Where(m => m.MethodKind == MethodKind.Ordinary))
            {
                if (classType.FindImplementationForInterfaceMember(member) != null)
                {
                    continue;
                }

                editor.AddMember(classDeclaration,
                                 GenerateMethodImplementation(gen,
                                                              model,
                                                              minificationLocation,
                                                              member,
                                                              Constants.ImplementationFieldName, includeAsyncAwait));
            }
        }
Ejemplo n.º 12
0
        private IEnumerable <CCodeUnit> BuildUnit(ITypeSymbol type, IAssembliesInfoResolver assembliesInfoResolver)
        {
            var unit = new CCodeUnit(type);

            var isNotModule            = type.Name != "<Module>";
            var isNotInterfaceOrModule = isNotModule && type.TypeKind != TypeKind.Interface;
            var methodSymbols          = type.GetMembers().OfType <IMethodSymbol>().ToList();
            var hasStaticConstructor   = methodSymbols.Any(m => m.MethodKind == MethodKind.StaticConstructor);

            foreach (var field in type.GetMembers().OfType <IFieldSymbol>())
            {
                this.BuildField(field, unit, hasStaticConstructor);
            }

            foreach (var @event in type.GetMembers().OfType <IEventSymbol>())
            {
                this.BuildField(new FieldImpl(@event), unit, hasStaticConstructor);
            }

            if (hasStaticConstructor)
            {
                BuildStaticConstructorVariables(type, unit);
            }

            if (isNotModule)
            {
                ////BuildTypeHolderVariables(type, unit);
                BuildTypeDescriptorVariables(type, unit);
            }

            var constructors = methodSymbols.Where(m => m.MethodKind == MethodKind.Constructor);

            foreach (var method in constructors)
            {
                this.BuildMethod(method, unit);
            }

            var finalizationRequired = type.BaseType != null && type.GetMembers().OfType <IMethodSymbol>().Any(m => m.MethodKind == MethodKind.Destructor);
            var isAtomicType         = type.IsAtomicType();
            var namedTypeSymbol      = (INamedTypeSymbol)type;

            if (isNotInterfaceOrModule)
            {
                unit.Declarations.Add(new CCodeNewOperatorDeclaration(namedTypeSymbol, finalizationRequired));
                unit.Declarations.Add(new CCodeNewOperatorDeclaration(namedTypeSymbol, finalizationRequired, debugVersion: true));
                unit.Declarations.Add(new CCodeNewOperatorDeclaration(namedTypeSymbol, finalizationRequired, true));
                unit.Declarations.Add(new CCodeNewOperatorDeclaration(namedTypeSymbol, finalizationRequired, true, true));
            }

            if (!isAtomicType && type.TypeKind != TypeKind.Interface)
            {
                unit.Declarations.Add(new CCodeGetTypeDescriptorDeclaration(namedTypeSymbol));
            }

            if (type.IsPrimitiveValueType() || type.TypeKind == TypeKind.Enum)
            {
                unit.Declarations.Add(new CCodeSpecialTypeOrEnumConstructorDeclaration(namedTypeSymbol, false));
            }

            /*
             * if (type.IsIntPtrType())
             * {
             *  unit.Declarations.Add(new CCodeSpecialTypeOrEnumConstructorDeclaration((INamedTypeSymbol)type, true));
             * }
             */

            // to support RuntimeType initialization
            if (type.IsRuntimeType())
            {
                unit.Declarations.Add(new CCodeRuntimeTypeConstructorDeclaration(namedTypeSymbol, true));
            }

            if (type.IsPrimitiveValueType() || type.TypeKind == TypeKind.Enum || type.IsIntPtrType())
            {
                unit.Declarations.Add(new CCodeCastOperatorDeclaration(namedTypeSymbol));
            }

            if (type.TypeKind == TypeKind.Struct)
            {
                unit.Declarations.Add(new CCodeArrowOperatorDeclaration(namedTypeSymbol));
            }

            if (isNotInterfaceOrModule)
            {
                // add internal infrustructure
                unit.Declarations.Add(new CCodeGetTypeVirtualMethodDeclaration(namedTypeSymbol));
                unit.Definitions.Add(new CCodeGetTypeVirtualMethodDefinition(namedTypeSymbol));
                unit.Declarations.Add(new CCodeIsTypeVirtualMethodDeclaration(namedTypeSymbol));
                unit.Definitions.Add(new CCodeIsTypeVirtualMethodDefinition(namedTypeSymbol));
                unit.Declarations.Add(new CCodeGetInterfaceVirtualMethodDeclaration(namedTypeSymbol));
                unit.Definitions.Add(new CCodeGetInterfaceVirtualMethodDefinition(namedTypeSymbol));
                if (!type.IsAbstract)
                {
                    unit.Declarations.Add(new CCodeCloneVirtualMethod(namedTypeSymbol));
                    unit.Declarations.Add(new CCodeGetSizeVirtualMethod(namedTypeSymbol));
                }

                if (type.SpecialType == SpecialType.System_Object)
                {
                    unit.Declarations.Add(new CCodeHashVirtualMethod(namedTypeSymbol));
                    unit.Declarations.Add(new CCodeEqualsVirtualMethod(namedTypeSymbol));
                }
            }

            if (type.TypeKind == TypeKind.Interface)
            {
                unit.Declarations.Add(new CCodeObjectCastOperatorDeclaration(namedTypeSymbol));
            }

            if (type.SpecialType == SpecialType.System_Array)
            {
                unit.Declarations.Add(new CCodeNewOperatorPointerDeclaration(namedTypeSymbol));
                unit.Declarations.Add(new CCodeGetArrayElementSizeVirtualMethod(namedTypeSymbol));
                unit.Declarations.Add(new CCodeIsPrimitiveTypeArrayVirtualMethod(namedTypeSymbol));
            }

            if (type.TypeKind == TypeKind.Interface)
            {
                // add all methods from all interfaces
                foreach (var method in type.EnumerateInterfaceMethods())
                {
                    unit.Declarations.Add(new CCodeMethodDeclaration(type, method));
                }
            }

            foreach (var method in methodSymbols.Where(m => m.MethodKind != MethodKind.Constructor))
            {
                this.BuildMethod(method, unit);
            }

            if (isNotModule)
            {
                BuildMethodTableVariables(type, unit);
                ////BuildRuntimeInfoVariables(type, unit);
            }

            if (isNotInterfaceOrModule)
            {
                // append interface calls
                foreach (var interfaceMethod in type.EnumerateInterfaceMethods())
                {
                    var method = interfaceMethod;
                    var implementationForInterfaceMember = type.FindImplementationForInterfaceMember(interfaceMethod) as IMethodSymbol;
                    if (implementationForInterfaceMember != null &&
                        implementationForInterfaceMember.ExplicitInterfaceImplementations.Any(ei => ei.Equals(method)))
                    {
                        continue;
                    }

                    Debug.Assert(implementationForInterfaceMember != null, "Method for interface can't be found");
                    unit.Declarations.Add(new CCodeInterfaceMethodAdapterDeclaration(type, interfaceMethod, implementationForInterfaceMember));
                    unit.Definitions.Add(new CCodeInterfaceMethodAdapterDefinition(type, interfaceMethod, implementationForInterfaceMember));
                }
            }

            yield return(unit);

            if (!isNotModule)
            {
                yield break;
            }

            // return type holder class
            var typeHolderType = (TypeImpl)TypeImpl.Wrap(type);

            if (!type.IsAnonymousType())
            {
                typeHolderType.Name         = typeHolderType.Name + "__type";
                typeHolderType.MetadataName = typeHolderType.MetadataName + "__type";
            }
            else
            {
                var namedType = (INamedTypeSymbol)type;
                typeHolderType.Name         = namedType.GetAnonymousTypeName() + "__type";
                typeHolderType.MetadataName = namedType.GetAnonymousTypeName() + "__type";
            }

            typeHolderType.BaseType      = null;
            typeHolderType.TypeKind      = TypeKind.Struct;
            typeHolderType.Interfaces    = ImmutableArray <INamedTypeSymbol> .Empty;
            typeHolderType.AllInterfaces = ImmutableArray <INamedTypeSymbol> .Empty;
            typeHolderType.SpecialType   = SpecialType.None;

            var unitTypeHolder = new CCodeUnit(typeHolderType);

            BuildTypeHolderVariables(typeHolderType, unitTypeHolder);
            ////BuildMethodTableVariables(typeHolderType, unitTypeHolder);
            BuildRuntimeInfoVariables(typeHolderType, type, unitTypeHolder);

            yield return(unitTypeHolder);
        }
Ejemplo n.º 13
0
 /// <summary>
 /// Determines whether the specified invocation target implements <see cref="System.Collections.ICollection"/>.
 /// </summary>
 /// <param name="invocationTarget">The invocation target.</param>
 /// <returns><see langword="true" /> if the specified invocation target implements <see cref="System.Collections.ICollection"/>; otherwise, <see langword="false" />.</returns>
 internal bool IsICollectionImplementation(ITypeSymbol invocationTarget)
 => this.ICollectionCountProperty is object &&
 invocationTarget.FindImplementationForInterfaceMember(this.ICollectionCountProperty) is IPropertySymbol countProperty &&
		/// <summary>
		///   Checks whether the <paramref name="symbol" />'s implementing member for <paramref name="interfaceMember" /> has the
		///   correct port kind.
		/// </summary>
		/// <param name="context">The context in which the analysis should be performed.</param>
		/// <param name="symbol">The symbol that should be analyzed.</param>
		/// <param name="compilation">The compilation the symbol is declared in.</param>
		/// <param name="interfaceMember">The interface member that should be checked.</param>
		private static void CheckMember(SymbolAnalysisContext context, ITypeSymbol symbol, Compilation compilation, ISymbol interfaceMember)
		{
			var implementingMember = symbol.FindImplementationForInterfaceMember(interfaceMember);

			var interfaceIsRequired = interfaceMember.HasAttribute<RequiredAttribute>(compilation);
			var interfaceIsProvided = interfaceMember.HasAttribute<ProvidedAttribute>(compilation);

			var implementationIsRequired = implementingMember.HasAttribute<RequiredAttribute>(compilation) || implementingMember.IsExtern;
			var implementationIsProvided = implementingMember.HasAttribute<ProvidedAttribute>(compilation) || !implementingMember.IsExtern;

			// If we can't uniquely classify the port kind of either the interface member or the implementation, 
			// there is another problem that another analyzer deals with. So let's just ignore it here.
			if ((interfaceIsRequired && interfaceIsProvided) || (implementationIsProvided && implementationIsRequired))
				return;

			var location = implementingMember.ContainingType.Equals(symbol) ? implementingMember : symbol;
			if (interfaceIsRequired && !implementationIsRequired)
			{
				_requiredPortImplementedAsProvidedPort.Emit(context, location,
					implementingMember.ToDisplayString(), interfaceMember.ToDisplayString());
			}

			if (interfaceIsProvided && !implementationIsProvided)
			{
				_providedPortImplementedAsRequiredPort.Emit(context, location,
					implementingMember.ToDisplayString(), interfaceMember.ToDisplayString());
			}
		}
Ejemplo n.º 15
0
        private CCodeUnit BuildUnit(ITypeSymbol type, IAssembliesInfoResolver assembliesInfoResolver)
        {
            var unit = new CCodeUnit(type);

            var methodSymbols        = type.GetMembers().OfType <IMethodSymbol>().ToList();
            var hasStaticConstructor = methodSymbols.Any(m => m.MethodKind == MethodKind.StaticConstructor);

            foreach (var field in type.GetMembers().OfType <IFieldSymbol>())
            {
                this.BuildField(field, unit, hasStaticConstructor);
            }

            if (hasStaticConstructor)
            {
                BuildStaticConstructorVariables(type, unit);
            }

            if (type.Name != "<Module>")
            {
                BuildTypeHolderVariables(type, unit);
            }

            var constructors = methodSymbols.Where(m => m.MethodKind == MethodKind.Constructor);

            foreach (var method in constructors)
            {
                this.BuildMethod(method, unit);
            }

            if (type.TypeKind != TypeKind.Interface && type.BaseType == null && type.Name != "<Module>")
            {
                unit.Declarations.Add(new CCodeNewOperatorDeclaration((INamedTypeSymbol)type));
                unit.Declarations.Add(new CCodeNewOperatorWithSizeDeclaration((INamedTypeSymbol)type));
            }

            if (type.IsPrimitiveValueType() || type.TypeKind == TypeKind.Enum)
            {
                unit.Declarations.Add(new CCodeSpecialTypeOrEnumConstructorDeclaration((INamedTypeSymbol)type));
            }

            if (type.IsPrimitiveValueType() || type.TypeKind == TypeKind.Enum || type.IsIntPtrType())
            {
                unit.Declarations.Add(new CCodeCastOperatorDeclaration((INamedTypeSymbol)type));
            }

            if (type.TypeKind == TypeKind.Struct)
            {
                unit.Declarations.Add(new CCodeArrowOperatorDeclaration((INamedTypeSymbol)type));
            }

            if (type.Name != "<Module>" && type.TypeKind != TypeKind.Interface)
            {
                // add internal infrustructure
                unit.Declarations.Add(new CCodeGetTypeVirtualMethodDeclaration((INamedTypeSymbol)type));
                unit.Definitions.Add(new CCodeGetTypeVirtualMethodDefinition((INamedTypeSymbol)type));
                unit.Declarations.Add(new CCodeIsTypeVirtualMethodDeclaration((INamedTypeSymbol)type));
                unit.Definitions.Add(new CCodeIsTypeVirtualMethodDefinition((INamedTypeSymbol)type));
                unit.Declarations.Add(new CCodeGetInterfaceVirtualMethodDeclaration((INamedTypeSymbol)type));
                unit.Definitions.Add(new CCodeGetInterfaceVirtualMethodDefinition((INamedTypeSymbol)type));
                if (!type.IsAbstract)
                {
                    unit.Declarations.Add(new CCodeCloneVirtualMethod((INamedTypeSymbol)type));
                }
            }

            if (type.TypeKind == TypeKind.Interface)
            {
                unit.Declarations.Add(new CCodeObjectCastOperatorDeclaration((INamedTypeSymbol)type));
            }

            if (type.SpecialType == SpecialType.System_Array)
            {
                unit.Declarations.Add(new CCodeGetArrayElementSizeVirtualMethod((INamedTypeSymbol)type));
            }

            if (type.TypeKind == TypeKind.Interface)
            {
                // add all methods from all interfaces
                foreach (var method in type.AllInterfaces.SelectMany(i => i.GetMembers().OfType <IMethodSymbol>()))
                {
                    unit.Declarations.Add(new CCodeMethodDeclaration(method));
                }
            }

            foreach (var method in methodSymbols.Where(m => m.MethodKind != MethodKind.Constructor))
            {
                this.BuildMethod(method, unit);
            }

            if (type.TypeKind != TypeKind.Interface)
            {
                // append interface calls
                foreach (var interfaceMethod in type.AllInterfaces.SelectMany(i => i.GetMembers().OfType <IMethodSymbol>()))
                {
                    var method = interfaceMethod;
                    var implementationForInterfaceMember = type.FindImplementationForInterfaceMember(interfaceMethod) as IMethodSymbol;
                    if (implementationForInterfaceMember != null &&
                        implementationForInterfaceMember.ExplicitInterfaceImplementations.Any(ei => ei.Equals(method)))
                    {
                        continue;
                    }

                    Debug.Assert(implementationForInterfaceMember != null, "Method for interface can't be found");
                    unit.Declarations.Add(new CCodeInterfaceMethodAdapterDeclaration(interfaceMethod, implementationForInterfaceMember));
                    unit.Definitions.Add(new CCodeInterfaceMethodAdapterDefinition(type, interfaceMethod, implementationForInterfaceMember));
                }
            }

            return(unit);
        }
 private static bool ImplementationMissing(ITypeSymbol parentClass, ISymbol i) =>
 parentClass.FindImplementationForInterfaceMember(i) == null;