예제 #1
0
        public void Test_GetNamespace_IgnoredNamespaceGeneric()
        {
            TypeDefinition testType = GetType(typeof(ReadOnlySpan <>).Module.FullyQualifiedName, "mdoc.Test.SampleClasses.ReadOnlySpan`1");
            var            ns       = DocUtils.GetNamespace(testType.GenericParameters.First());

            Assert.AreEqual("", ns);
        }
        protected override StringBuilder AppendNamespace(StringBuilder buf, TypeReference type)
        {
            string ns = DocUtils.GetNamespace(type, NestedTypeSeparator);

            if (GetCppType(type.FullName) == null && !string.IsNullOrEmpty(ns) && ns != "System")
            {
                buf.Append(ns).Append(NestedTypeSeparator);
            }
            return(buf);
        }
예제 #3
0
        protected override StringBuilder AppendNamespace(StringBuilder buf, TypeReference type)
        {
            string ns = DocUtils.GetNamespace(type);

            if (GetCSharpType(type.FullName) == null && ns != null && ns.Length > 0 && ns != "System")
            {
                buf.Append(ns).Append('.');
            }
            return(buf);
        }
        private bool IsCustomAttribute(TypeDefinition typedef)
        {
            var containingTypeNamespace = DocUtils.GetNamespace(typedef);

            if (typedef.BaseType?.FullName == "System.Attribute" && !containingTypeNamespace.StartsWith("System.") && !containingTypeNamespace.StartsWith("System"))
            {
                return(true);
            }

            return(false);
        }
예제 #5
0
        protected override StringBuilder AppendNamespace(StringBuilder buf, TypeReference type)
        {
            if (GetBuiltinType(type.FullName) != null)
            {
                return(buf);
            }
            string ns = DocUtils.GetNamespace(type);

            if (ns != null && ns.Length > 0)
            {
                if (type.IsValueType)
                {
                    buf.Append("valuetype ");
                }
                else
                {
                    buf.Append("class ");
                }
                buf.Append(ns).Append('.');
            }
            return(buf);
        }
        public override bool IsSupported(TypeReference tref)
        {
            if (HasNestedClassesDuplicateNames(tref))
            {
                return(false);
            }

            var ns           = DocUtils.GetNamespace(tref);
            var allowedTypes = GetAllowedTypes();

            if (allowedTypes.Contains(tref.FullName.Split(' ')[0])
                //winRt specific namespaces so no need for further check
                || ns.StartsWith("Windows.")
                )
            {
                return(true);
            }

            TypeDefinition typedef = null;

            try
            {
                typedef = tref.Resolve();
            }
            catch
            {
                //for winRt Resolve() can fail as Cecil understands winRt types as .net (eg, "System.Object" cannot be resolved)
            }

            if (typedef != null)
            {
                if (allowedTypes.Contains(typedef.FullName))
                {
                    //to check type of array
                    return(true);
                }

                if (DocUtils.IsDelegate(typedef))
                {
                    //delegates can be used only in managed context
                    return(false);
                }

                if (typedef.HasGenericParameters &&
                    typedef.GenericParameters.Any(x => x.HasConstraints ||
                                                  x.HasReferenceTypeConstraint ||
                                                  x.HasDefaultConstructorConstraint ||
                                                  x.HasNotNullableValueTypeConstraint)
                    )
                {
                    //Type parameters cannot be constrained
                    return(false);
                }

                if (HasUnsupportedParent(typedef))
                {
                    return(false);
                }
            }

            return(IsSupportedGenericParameter(tref) &&
                   !ns.StartsWith("System.") && !ns.Equals("System"));
        }
        protected bool HasUnsupportedParent(TypeDefinition typedef)
        {
            var            collect            = new List <TypeDefinition>();
            TypeReference  baseTypeReference  = typedef.BaseType;
            TypeDefinition basetypeDefenition = null;

            var allowedTypes = GetAllowedTypes();

            try
            {
                //iterate through all classes in in inheritance hierarhy to exclude usage of .net types
                basetypeDefenition = baseTypeReference?.Resolve();
                while (basetypeDefenition != null)
                {
                    if (allowedTypes.Contains(basetypeDefenition.FullName) || basetypeDefenition.BaseType == null)
                    {
                        break;
                    }

                    collect.Add(basetypeDefenition);

                    //needs to call Resolve to grab all base classes
                    basetypeDefenition = basetypeDefenition.BaseType?.Resolve();
                }
            }
            catch (Exception)
            {
                //for c++/cx Resolve() can fail as Cecil understands types as .net (eg, "System.Attribute" instead of "Platform::Metadata::Attribute")
                //needs to ignore those errors
                baseTypeReference = basetypeDefenition?.BaseType ?? baseTypeReference;
            }

            if (collect.Any(x => DocUtils.GetNamespace(x).StartsWith("System.") || DocUtils.GetNamespace(x).Equals("System")) ||
                !allowedTypes.Contains(baseTypeReference?.FullName) &&
                (
                    DocUtils.GetNamespace(baseTypeReference).StartsWith("System.") ||
                    DocUtils.GetNamespace(baseTypeReference).Equals("System")
                )
                )
            {
                //can only be Windows Runtime types(no support for .net types)
                return(true);
            }

            try
            {
                IEnumerable <TypeReference> interfaceNames = DocUtils.GetUserImplementedInterfaces(typedef).ToList();

                if (interfaceNames.Any(x => DocUtils.GetNamespace(x).StartsWith("System.") || DocUtils.GetNamespace(x).Equals("System")))
                {
                    //can only be Windows Runtime types(no support for .net types)
                    return(true);
                }
            }
            catch
            {
                //for c++/cx Resolve() can fail as Cecil understands types as .net (eg, "System.Attribute" instead of "Platform::Metadata::Attribute")
                //needs to ignore those errors
            }

            return(false);
        }
        public override bool IsSupported(TypeReference tref)
        {
            if (HasNestedClassesDuplicateNames(tref))
            {
                return(false);
            }

            var allowedTypes = GetAllowedTypes();

            //no support of jagged arrays
            if (tref is ArrayType)
            {
                var typeOfArray = tref is TypeSpecification spec ? spec.ElementType : tref.GetElementType();
                if (typeOfArray is ArrayType)
                {
                    return(false);
                }

                if (allowedTypes.Contains(typeOfArray.FullName) ||
                    CppCxSpecificNamespases.Contains(typeOfArray.Namespace))
                {
                    return(true);
                }
            }

            if (allowedTypes.Contains(tref.FullName.Split(' ')[0]) || CppCxSpecificNamespases.Contains(tref.Namespace))
            {
                return(true);
            }

            var ns = DocUtils.GetNamespace(tref);

            var typedef = tref.Resolve();

            if (typedef != null)
            {
                if (DocUtils.IsDelegate(typedef))
                {
                    if (typedef.HasGenericParameters && typedef.IsPublic)
                    {
                        //generic delegates cannot be declared as public
                        return(false);
                    }

                    return
                        //check types of delegate signature
                        (IsSupported(typedef.GetMethod("Invoke"))
                         //check type
                         && base.IsSupported(tref) && !(ns.StartsWith("System.") || ns.StartsWith("System")));
                }

                if (typedef.IsInterface && typedef.HasGenericParameters &&
                    typedef.GenericParameters.Any(x => x.HasConstraints ||
                                                  x.HasReferenceTypeConstraint ||
                                                  x.HasDefaultConstructorConstraint ||
                                                  x.HasNotNullableValueTypeConstraint)
                    )
                {
                    //generic interface - Type parameters cannot be constrained
                    return(false);
                }

                if (HasUnsupportedParent(typedef))
                {
                    return(false);
                }

                var typeVisibility = typedef.Attributes & TypeAttributes.VisibilityMask;

                if (typeVisibility == TypeAttributes.Public
                    //all public types, including those in your own code, must be declared in a namespace
                    && (string.IsNullOrEmpty(ns)
                        //public standard C++ types are not allowed
                        || ns.StartsWith("std") || ns.StartsWith("cli"))
                    )
                {
                    return(false);
                }

                if (typeVisibility == TypeAttributes.NestedPublic &&
                    (typedef.IsEnum || typedef.IsClass)
                    )
                {
                    //no support of nested public classes/enums
                    return(false);
                }

                if (typedef.IsClass && typeVisibility == TypeAttributes.Public && typedef.HasGenericParameters)
                {
                    //Public ref classes that have type parameters (generics) are not permitted.
                    return(false);
                }

                if (typedef.IsClass && typeVisibility == TypeAttributes.Public)
                {
                    //A public ref class that has a public constructor must also be declared as sealed
                    //to prevent further derivation through the application binary interface (ABI).
                    if (typedef.Methods.Any(x => x.IsConstructor && x.IsPublic) && !typedef.IsSealed)
                    {
                        return(false);
                    }
                }

                if (typedef.IsValueType && !typedef.IsEnum && typedef.Fields.Any(x =>
                                                                                 !ValueClassPropertyTypeAllowed.Contains(x.FieldType.FullName) && !(x.FieldType.Resolve() != null && x.FieldType.Resolve().IsEnum)))
                {
                    //A value struct or value class can contain as fields only
                    //fundamental numeric types, enum classes, Platform::String^, or Platform::IBox <T>^
                    return(false);
                }


                bool condition;
                try
                {
                    //custom attribute can contain only public fields and only with allowed types or enums
                    condition = IsCustomAttribute(typedef) &&
                                (typedef.Fields.Any(z =>
                                                    !CustomAttributesFieldTypesAllowed.Contains(z.FieldType.FullName) &&
                                                    !(z.FieldType.Resolve() != null && z.FieldType.Resolve().IsEnum)
                                                    ) ||
                                 typedef.Properties.Count != 0 ||
                                 typedef.Methods.Count(x => !x.IsConstructor) != 0 ||
                                 typedef.Events.Count != 0
                                );
                }
                catch
                {
                    condition = false;
                }

                if (condition)
                {
                    //custom attribute can contain only public fields and only with allowed types or enums
                    return(false);
                }
            }

            //cannot support .Net types
            return(!ns.StartsWith("System.") && !ns.Equals("System") && base.IsSupported(tref));
        }