Xamarin Public Jenkins (auto-signing) 95fdb59ea6 Imported Upstream version 6.6.0.89
Former-commit-id: b39a328747c2f3414dc52e009fb6f0aa80ca2492
2019-09-24 08:53:40 +00:00

169 lines
7.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 doesnt 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 youre 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 doesnt 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;
}
}
}