You've already forked linux-packaging-mono
							
							
		
			
	
	
		
			169 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			169 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
|   | using System.Collections.Generic; | |||
|  | using System.Linq; | |||
|  | using System.Text; | |||
|  | using Mono.Cecil; | |||
|  | using Mono.Cecil.Rocks; | |||
|  | using Mono.Collections.Generic; | |||
|  | using Mono.Documentation.Updater; | |||
|  | using Mono.Documentation.Util; | |||
|  | 
 | |||
|  | namespace mdoc.Mono.Documentation.Updater.Formatters | |||
|  | { | |||
|  |     public class JsFormatter : MemberFormatter | |||
|  |     { | |||
|  |         // For the V1 Pri1 implementation, we will not implement custom “retrievers”.  | |||
|  |         // If a non-static class doesn’t have a public constructor  | |||
|  |         // (in other words, it is not possible to automatically determine the call to instantiate an instance of the class),  | |||
|  |         // the Javascript syntax should either: | |||
|  |         //  | |||
|  |         // show a standard disclaimer such as: | |||
|  |         // “This class does not provide a public constructor” or | |||
|  |         // “See the remarks section for information on obtaining an instance of this class” | |||
|  |         // Give a degenerate declarative syntax, such as simply: “Windows.System.FolderLauncherOptions” for the FolderLauncherOptions class. | |||
|  |         // The specific solution to use here is still TBD. If you’re blocked, pick A1 for now. | |||
|  |         // We will investigate whether a Pri 2 feature to modify the syntax block with custom syntax is necessary. | |||
|  |         public override bool IsSupported(TypeReference tref) | |||
|  |         { | |||
|  |             var type = tref.Resolve(); | |||
|  | 
 | |||
|  |             if (type == null | |||
|  |                 || type.IsAbstract | |||
|  |                 || type.IsInterface// Interfaces: You cannot implement a Windows Runtime interface in JavaScript. | |||
|  |                 || type.HasGenericParameters | |||
|  |                 || !IsSupported(type.CustomAttributes) | |||
|  |                 || type.DeclaringType != null)//WinRT type can not be nested | |||
|  |             { | |||
|  |                 return false; | |||
|  |             } | |||
|  | 
 | |||
|  |             if (type.IsEnum || | |||
|  |                 type.IsValueType || | |||
|  |                 DocUtils.IsDelegate(type)) | |||
|  |             { | |||
|  |                 if (type.IsEnum && !IsEnumSupported(type)) return false; | |||
|  | 
 | |||
|  |                 return true; | |||
|  |             } | |||
|  |              | |||
|  |             // Windows Runtime types cannot have multiple constructors with same number of arguments | |||
|  |             var publicConstructors = type.GetConstructors().Where(i => i.IsPublic).ToList(); | |||
|  |             if (!publicConstructors.Any()) | |||
|  |                 return false; | |||
|  | 
 | |||
|  |             var constructorsWithEqualNumberOfArguments = publicConstructors.GroupBy(x => x.Parameters.Count) | |||
|  |                 .Where(g => g.Count() > 1) | |||
|  |                 .Select(y => y.Key) | |||
|  |                 .ToList(); | |||
|  | 
 | |||
|  |             return constructorsWithEqualNumberOfArguments.Count == 0; | |||
|  |         } | |||
|  | 
 | |||
|  |         protected virtual bool IsEnumSupported(TypeDefinition type) | |||
|  |         { | |||
|  |             return type.GetMembers().Skip(1).Any();//skip "__value element" | |||
|  |         } | |||
|  | 
 | |||
|  |         public override bool IsSupported(MemberReference mref) | |||
|  |         { | |||
|  |             switch (mref) | |||
|  |             { | |||
|  |                 case PropertyDefinition propertyDefinition: | |||
|  |                     if (!IsPropertySupported(propertyDefinition)) | |||
|  |                         return false; | |||
|  |                     break; | |||
|  |                 case MethodDefinition methodDefinition: | |||
|  |                     if (!IsMethodSupported(methodDefinition)) | |||
|  |                         return false; | |||
|  |                     break; | |||
|  |                 case FieldDefinition _: | |||
|  |                     return false;// In WinRT fields can be exposed only by structures. | |||
|  |                 case AttachedEventDefinition _: | |||
|  |                     return false; | |||
|  |                 case AttachedPropertyDefinition _: | |||
|  |                     return false; | |||
|  |             } | |||
|  | 
 | |||
|  |             var member = mref.Resolve(); | |||
|  |             return member != null | |||
|  |                    && !member.DeclaringType.HasGenericParameters | |||
|  |                    && !(mref is IGenericParameterProvider genericParameterProvider && genericParameterProvider.HasGenericParameters) | |||
|  |                    && !(mref is IMethodSignature methodSignature && methodSignature.Parameters.Any(i => i.ParameterType is GenericParameter)) | |||
|  |                    && mref.DeclaringType.DeclaringType == null//WinRT type can not be nested | |||
|  |                    && IsSupported(member.CustomAttributes); | |||
|  |         } | |||
|  | 
 | |||
|  |         private bool IsMethodSupported(MethodDefinition methodDefinition) | |||
|  |         { | |||
|  |             bool isDestructor = DocUtils.IsDestructor(methodDefinition); | |||
|  |             return | |||
|  |                 !DocUtils.IsOperator(methodDefinition) | |||
|  |                 && (!isDestructor || methodDefinition.DeclaringType.Interfaces.Any(i => i.InterfaceType.FullName == "Windows.Foundation.IClosable")) | |||
|  |                 && methodDefinition.Parameters.All(i => IsSupported(i.CustomAttributes) && !(i.ParameterType is ByReferenceType)) | |||
|  |                 && IsSupported(methodDefinition.MethodReturnType.CustomAttributes); | |||
|  |         } | |||
|  | 
 | |||
|  |         // How to determine if an API supports JavaScript | |||
|  |         // Use the WebHostHidden attribute. If WebHostHidden is present, the API doesn’t support JavaScript. | |||
|  |         // None of the APIs in the “XAML” namespaces support JavaScript. | |||
|  |         protected  bool IsSupported(Collection<CustomAttribute> memberCustomAttributes) | |||
|  |         { | |||
|  |             return | |||
|  |                 memberCustomAttributes.All( | |||
|  |                     i => i.AttributeType.FullName != "Windows.Foundation.Metadata.WebHostHiddenAttribute"); | |||
|  |         } | |||
|  | 
 | |||
|  |         protected virtual bool IsPropertySupported(PropertyDefinition property) | |||
|  |         { | |||
|  |             bool getVisible = property.GetMethod != null && property.GetMethod.IsPublic; | |||
|  |             bool setVisible = property.SetMethod != null && property.SetMethod.IsPublic; | |||
|  |             if (!setVisible && !getVisible) | |||
|  |                 return false; | |||
|  | 
 | |||
|  |             IEnumerable<MemberReference> defs = property.DeclaringType.GetDefaultMembers(); | |||
|  |             foreach (MemberReference mi in defs) | |||
|  |             { | |||
|  |                 if (mi == property) | |||
|  |                 { | |||
|  |                     return false; | |||
|  |                 } | |||
|  |             } | |||
|  |             return property.Parameters.Count == 0; | |||
|  |         } | |||
|  | 
 | |||
|  |         protected override StringBuilder AppendParameters(StringBuilder buf, MethodDefinition method, IList<ParameterDefinition> parameters) | |||
|  |         { | |||
|  |             return buf.Append(string.Join(", ", parameters.Select(i => i.Name))); | |||
|  |         } | |||
|  | 
 | |||
|  |         protected MethodDefinition GetConstructor(TypeDefinition type) | |||
|  |         { | |||
|  |             return type.GetConstructors() | |||
|  |                 .Where(i => i.IsPublic) | |||
|  |                 .OrderByDescending(i => i.Parameters.Count) | |||
|  |                 .First(); | |||
|  |         } | |||
|  | 
 | |||
|  |         protected override string GetMethodName(MethodReference method) | |||
|  |         { | |||
|  |             if (DocUtils.IsDestructor(method.Resolve())) | |||
|  |                 return "Close"; | |||
|  |             return CamelCase(method.Name); | |||
|  |         } | |||
|  | 
 | |||
|  |         protected override string GetTypeName(TypeReference type, DynamicParserContext context, bool appendGeneric = true) | |||
|  |         { | |||
|  |             int n = type.Name.IndexOf("`"); | |||
|  |             if (n >= 0) | |||
|  |                 return type.Name.Substring(0, n); | |||
|  |             return type.Name; | |||
|  |         } | |||
|  | 
 | |||
|  |         protected string ProcessFullName(string fullName) | |||
|  |         { | |||
|  |             int n = fullName.IndexOf("`"); | |||
|  |             if (n >= 0) | |||
|  |                 return fullName.Substring(0, n); | |||
|  |             return fullName; | |||
|  |         } | |||
|  |     } | |||
|  | } |