コード例 #1
0
        public virtual bool TryFormatValue(object v, ResolvedTypeInfo type, out string returnvalue)
        {
            TypeReference valueType = type.Reference;

            if (v == null)
            {
                returnvalue = "null";
                return(true);
            }
            if (valueType.FullName == "System.Type")
            {
                var vTypeRef = v as TypeReference;
                if (vTypeRef != null)
                {
                    returnvalue = "typeof(" + NativeTypeManager.GetTranslatedName(vTypeRef) + ")";  // TODO: drop NS handling
                }
                else
                {
                    returnvalue = "typeof(" + v.ToString() + ")";
                }

                return(true);
            }
            if (valueType.FullName == "System.String")
            {
                returnvalue = "\"" + FilterSpecialChars(v.ToString()) + "\"";
                return(true);
            }
            if (valueType.FullName == "System.Char")
            {
                returnvalue = "'" + FilterSpecialChars(v.ToString()) + "'";
                return(true);
            }
            if (v is Boolean)
            {
                returnvalue = (bool)v ? "true" : "false";
                return(true);
            }

            TypeDefinition valueDef = type.Definition;

            if (valueDef == null || !valueDef.IsEnum)
            {
                returnvalue = v.ToString();
                return(true);
            }

            string typename = MDocUpdater.GetDocTypeFullName(valueType);
            var    values   = GetEnumerationValues(valueDef);
            long   c        = ToInt64(v);

            if (values.ContainsKey(c))
            {
                returnvalue = typename + "." + values[c];
                return(true);
            }

            returnvalue = null;
            return(false);
        }
コード例 #2
0
        public static MemberReference GetMember(TypeDefinition type, DocumentationMember member)
        {
            string membertype = member.MemberType;

            string returntype = member.ReturnType;

            string docName = member.MemberName;

            string[] docTypeParams = GetTypeParameters(docName, member.TypeParameters);

            // If we're using 'magic types', then we might get false positives ... in those cases, we keep searching
            MemberReference likelyCandidate = null;

            // Loop through all members in this type with the same name
            var reflectedMembers = GetReflectionMembers(type, docName, membertype).ToArray();

            foreach (MemberReference mi in reflectedMembers)
            {
                bool matchedMagicType = false;
                if (mi is TypeDefinition)
                {
                    continue;
                }
                if (MDocUpdater.GetMemberType(mi) != membertype)
                {
                    continue;
                }

                if (MDocUpdater.IsPrivate(mi))
                {
                    continue;
                }

                IList <ParameterDefinition> pis = null;
                string[] typeParams             = null;
                if (mi is MethodDefinition)
                {
                    MethodDefinition mb = (MethodDefinition)mi;
                    pis = mb.Parameters;
                    if (mb.IsGenericMethod())
                    {
                        IList <GenericParameter> args = mb.GenericParameters;
                        typeParams = args.Select(p => p.Name).ToArray();
                    }
                }
                else if (mi is PropertyDefinition)
                {
                    pis = ((PropertyDefinition)mi).Parameters;
                }

                // check type parameters
                int methodTcount     = member.TypeParameters == null ? 0 : member.TypeParameters.Count;
                int reflectionTcount = typeParams == null ? 0 : typeParams.Length;
                if (methodTcount != reflectionTcount)
                {
                    continue;
                }

                // check member parameters
                int mcount = member.Parameters == null ? 0 : member.Parameters.Count;
                int pcount = pis == null ? 0 : pis.Count;
                if (mcount != pcount)
                {
                    continue;
                }

                MethodDefinition mDef = mi as MethodDefinition;
                if (mDef != null && !mDef.IsConstructor && (mDef.Name.StartsWith("op_Explicit", StringComparison.Ordinal) || mDef.Name.StartsWith("op_Implicit", StringComparison.Ordinal)))
                {
                    // Casting operators can overload based on return type.
                    string rtype = GetReplacedString(
                        MDocUpdater.GetDocTypeFullName(((MethodDefinition)mi).ReturnType),
                        typeParams, docTypeParams);
                    string originalRType = rtype;
                    if (MDocUpdater.SwitchingToMagicTypes)
                    {
                        rtype = NativeTypeManager.ConvertFromNativeType(rtype);
                    }
                    if ((returntype != rtype && originalRType == rtype) ||
                        (MDocUpdater.SwitchingToMagicTypes && returntype != originalRType && returntype != rtype && originalRType != rtype))
                    {
                        continue;
                    }

                    if (originalRType != rtype)
                    {
                        matchedMagicType = true;
                    }
                }

                if (pcount == 0)
                {
                    return(mi);
                }
                bool isExtensionMethod = DocUtils.IsExtensionMethod(mDef);
                bool good = true;
                for (int i = 0; i < pis.Count; i++)
                {
                    bool isRefType = pis[i].ParameterType is ByReferenceType;

                    if (i == 0 && !isRefType && isExtensionMethod)
                    {
                        isRefType = true; // this will be the case for generic parameter types
                    }
                    string paramType = GetReplacedString(
                        MDocUpdater.GetDocParameterType(pis[i].ParameterType),
                        typeParams, docTypeParams);

                    // if magictypes, replace paramType to "classic value" ... so the comparison works
                    string originalParamType = paramType;
                    if (MDocUpdater.SwitchingToMagicTypes)
                    {
                        paramType = NativeTypeManager.ConvertFromNativeType(paramType);
                    }

                    string xmlMemberType = member.Parameters[i];

                    // TODO: take into account extension method reftype
                    bool xmlIsRefType  = xmlMemberType.Contains('&');
                    bool refTypesMatch = isRefType == xmlIsRefType;

                    if (!refTypesMatch)
                    {
                        good = false;
                        break;
                    }

                    xmlMemberType = xmlIsRefType ? xmlMemberType.Substring(0, xmlMemberType.Length - 1) : xmlMemberType;

                    if ((!paramType.Equals(xmlMemberType) && paramType.Equals(originalParamType)) ||
                        (MDocUpdater.SwitchingToMagicTypes && !originalParamType.Equals(xmlMemberType) && !paramType.Equals(xmlMemberType) && !paramType.Equals(originalParamType)))
                    {
                        // did not match ... if we're dropping the namespace, and the paramType has the dropped
                        // namespace, we should see if it matches when added
                        bool stillDoesntMatch = true;
                        if (MDocUpdater.HasDroppedNamespace(type) && paramType.StartsWith(MDocUpdater.droppedNamespace))
                        {
                            string withDroppedNs = string.Format("{0}.{1}", MDocUpdater.droppedNamespace, xmlMemberType);

                            stillDoesntMatch = withDroppedNs != paramType;
                        }

                        if (stillDoesntMatch)
                        {
                            good = false;
                            break;
                        }
                    }

                    if (originalParamType != paramType)
                    {
                        matchedMagicType = true;
                    }
                }
                if (!good)
                {
                    continue;
                }

                if (MDocUpdater.SwitchingToMagicTypes && likelyCandidate == null && matchedMagicType)
                {
                    // we matched this on a magic type conversion ... let's keep going to see if there's another one we should look at that matches more closely
                    likelyCandidate = mi;
                    continue;
                }

                return(mi);
            }

            return(likelyCandidate);
        }
コード例 #3
0
ファイル: assembler.cs プロジェクト: v-zazhou/api-doc-tools
        void RewriteCrefsIfNecessary(XDocument doc, string path)
        {
            // we also have to rewrite crefs
            var sees = doc.Descendants().Where(d => d.Name.LocalName == "see").ToArray();

            foreach (var see in sees)
            {
                var cref = see.Attribute("cref");
                if (cref == null)
                {
                    continue;
                }
                EcmaUrlParser parser = new EcmaUrlParser();
                EcmaDesc      reference;
                if (!parser.TryParse(cref.Value, out reference))
                {
                    continue;
                }
                if ((new EcmaDesc.Kind[] {
                    EcmaDesc.Kind.Constructor,
                    EcmaDesc.Kind.Method
                }).Any(k => k == reference.DescKind))
                {
                    string ns         = reference.Namespace;
                    string type       = reference.TypeName;
                    string memberName = reference.MemberName;
                    if (reference.MemberArguments != null)
                    {
                        XDocument refDoc = FindReferenceDoc(path, doc, ns, type);
                        if (refDoc == null)
                        {
                            continue;
                        }
                        // look in the refDoc for the memberName, and match on parameters and # of type parameters
                        var overloads = refDoc.XPathSelectElements("//Member[@MemberName='" + memberName + "']").ToArray();
                        // Do some initial filtering to find members that could potentially match (based on parameter and typeparam counts)
                        var members = overloads.Where(e => reference.MemberArgumentsCount == e.XPathSelectElements("Parameters/Parameter[not(@apistyle) or @apistyle='classic']").Count() && reference.GenericMemberArgumentsCount == e.XPathSelectElements("TypeParameters/TypeParameter[not(@apistyle) or @apistyle='classic']").Count()).Select(m => new {
                            Node          = m,
                            AllParameters = m.XPathSelectElements("Parameters/Parameter").ToArray(),
                            Parameters    = m.XPathSelectElements("Parameters/Parameter[not(@apistyle) or @apistyle='classic']").ToArray(),
                            NewParameters = m.XPathSelectElements("Parameters/Parameter[@apistyle='unified']").ToArray()
                        }).ToArray();
                        // now find the member that matches on types
                        var member = members.FirstOrDefault(m => reference.MemberArguments.All(r => m.Parameters.Any(mp => mp.Attribute("Type").Value.Contains(r.TypeName))));
                        if (member == null || member.NewParameters.Length == 0)
                        {
                            continue;
                        }
                        foreach (var arg in reference.MemberArguments)
                        {
                            // find the "classic" parameter
                            var oldParam = member.Parameters.First(p => p.Attribute("Type").Value.Contains(arg.TypeName));
                            var newParam = member.NewParameters.FirstOrDefault(p => oldParam.Attribute("Name").Value == p.Attribute("Name").Value);
                            if (newParam != null)
                            {
                                // this means there was a change made, and we should try to convert this cref
                                arg.TypeName = NativeTypeManager.ConvertToNativeType(arg.TypeName);
                            }
                        }
                        var rewrittenReference = reference.ToEcmaCref();
                        Console.WriteLine("From {0} to {1}", cref.Value, rewrittenReference);
                        cref.Value = rewrittenReference;
                    }
                }
            }
        }