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); }
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); }
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)); }