private void WriteMethod(MethodTarget target, ReferenceLinkDisplayOptions options, XmlWriter writer, IDictionary <IndexedTemplateTypeReference, TypeReference> dictionary) { WriteProcedureName(target, options, writer); if ((options & ReferenceLinkDisplayOptions.ShowTemplates) > 0) { // if this is a generic method, write any template params or args if (target.TemplateArgs != null && target.TemplateArgs.Count > 0) { WriteTemplateArguments(target.TemplateArgs, writer); } } if ((options & ReferenceLinkDisplayOptions.ShowParameters) > 0) { IList <Parameter> parameters = target.Parameters; if (target.ConversionOperator) { TypeReference returns = target.returnType; WriteConversionOperatorParameters(parameters, returns, writer, dictionary); } else { WriteMethodParameters(parameters, writer, dictionary); } } }
public static ProcedureTarget ReadProcedureTarget(XmlReader reader) { if (reader == null || reader.NodeType != XmlNodeType.Element) { return(null); } switch (reader.Name) { case "ProcedureTarget": ProcedureTarget procedTarget = new ProcedureTarget(); procedTarget.ReadXml(reader); return(procedTarget); case "EventTarget": EventTarget eventTarget = new EventTarget(); eventTarget.ReadXml(reader); return(eventTarget); case "PropertyTarget": PropertyTarget propertyTarget = new PropertyTarget(); propertyTarget.ReadXml(reader); return(propertyTarget); case "MethodTarget": MethodTarget methodTarget = new MethodTarget(); methodTarget.ReadXml(reader); return(methodTarget); } return(null); }
private void WriteMemberTarget(MemberTarget target, ReferenceLinkDisplayOptions options, XmlWriter writer, IDictionary <IndexedTemplateTypeReference, TypeReference> dictionary) { if (target == null) { throw new ArgumentNullException("target"); } if (writer == null) { throw new ArgumentNullException("writer"); } if ((options & ReferenceLinkDisplayOptions.ShowContainer) > 0) { TypeReference type = target.Type; WriteType(type, options & ~ReferenceLinkDisplayOptions.ShowContainer, writer); if (target.TargetType == TargetType.Method) { MethodTarget methodTarget = (MethodTarget)target; if (methodTarget.conversionOperator) { writer.WriteString(" "); } else { WriteSeperator(writer); } } else { WriteSeperator(writer); } } switch (target.TargetType) { case TargetType.Method: // special logic for writing methods WriteMethod((MethodTarget)target, options, writer, dictionary); return; case TargetType.Property: // special logic for writing properties WriteProperty((PropertyTarget)target, options, writer); return; case TargetType.Constructor: // special logic for writing constructors WriteConstructor((ConstructorTarget)target, options, writer); return; case TargetType.Event: // special logic for writing events WriteEvent((EventTarget)target, options, writer); return; } // by default, just write name writer.WriteString(target.Name); }
public void TargetMethodSwitch(MethodTarget methodTarget) { switch (methodTarget) { default: break; } }
internal MethodCandidate(MethodTarget target, List <ParameterWrapper> parameters) { Debug.Assert(target != null); _target = target; _parameters = parameters; _narrowingLevel = NarrowingLevel.None; parameters.TrimExcess(); }
public void Method_Converter_Test() { TargetIdConverter conv = new TargetIdConverter("M:java.lang.Boolean.booleanValue"); Target target = conv.ToTarget(); Assert.AreEqual(LinkType2.External, target.DefaultLinkType); Assert.IsInstanceOf <MethodTarget>(target); MethodTarget mt = (MethodTarget)target; Assert.AreEqual("booleanValue", mt.Name); //Assert.AreEqual("java.lang", tt.Container); //Assert.IsNotNull(mt.Type); CollectionAssert.IsEmpty(mt.Templates); CollectionAssert.IsEmpty(mt.Parameters); CollectionAssert.IsEmpty(mt.TemplateArgs); }
public void Remove(TDelegate target) { if (null == target) { return; } foreach (Delegate d in (target as Delegate).GetInvocationList()) { MethodTarget mt = _targets.Find(w => Equals(d.Target, w.Reference?.Target) && Equals(d.Method.MethodHandle, w.Method.MethodHandle)); if (mt != null) { _targets.Remove(mt); } } }
private string GetTemplateName(string templateId, int position) { Target target = _targets[templateId]; if (target == null) { return("UTT"); } else { TargetType targetType = target.TargetType; if (targetType == TargetType.Type || targetType == TargetType.Enumeration) { TypeTarget type = (TypeTarget)target; IList <string> templates = type.Templates; if (templates.Count > position) { return(templates[position]); } else { return("UTT"); } } if (targetType == TargetType.Method) { MethodTarget method = (MethodTarget)target; IList <string> templates = method.Templates; if (templates.Count > position) { return(templates[position]); } else { return("UTT"); } } return("UTT"); } }
private MethodTarget ToMethod() { MethodTarget mt = new MethodTarget(); mt.Templates = new string[0]; mt.Parameters = new Parameter[0]; mt.TemplateArgs = new TypeReference[0]; Match match = MethodPattern.Match(this.targetId); if (!match.Success) { throw new InvalidOperationException( String.Format("TargetId with value '{0}' cannot be parsed as method name.", targetId)); } mt.Name = match.Groups[4].Value; // optional namespace mt.SetTypeReference(null); // match.Groups[2]; return(mt); }
private static MethodTarget CreateMethodTarget(XPathNavigator api) { MethodTarget target = new MethodTarget(); target.parameters = CreateParameterList(api); target.returnType = CreateReturnType(api); target.conversionOperator = (bool)api.Evaluate(apiIsConversionOperatorExpression); if ((bool)api.Evaluate(apiIsExplicitImplementationExpression)) { target.explicitlyImplements = CreateMemberReference( api.SelectSingleNode(apiImplementedMembersExpression)); } // this selects templates/template or templates/type, because extension methods can have a mix of generic and specialization XPathNodeIterator templateArgNodes = api.Select(methodTemplateArgsExpression); List <TypeReference> templateArgumentReferences = null; if (templateArgNodes != null && templateArgNodes.Count > 0) { templateArgumentReferences = new List <TypeReference>(templateArgNodes.Count); int i = 0; foreach (XPathNavigator templateArgNode in templateArgNodes) { templateArgumentReferences.Add(CreateTypeReference(templateArgNode)); i++; } } target.templateArgs = templateArgumentReferences; // get the short name of each template param target.templates = GetTemplateNames(api); return(target); }
public void Setup() { instance = new TypeTarget(typeof(TypeTargetTesterClass)); methodTarget = instance.Methods.Where(x => x.Name == "SomeGenericMethod").FirstOrDefault(); }
public int CompareTo(MethodTarget other, CallType callType) { ParameterComparison cmpParams = CompareParameters(this.parameters, other.parameters); if (cmpParams == ParameterComparison.First) return 1; if (cmpParams == ParameterComparison.Second) return -1; int ret = CompareEqualParameters(other); if (ret != 0) return ret; if (method.IsStatic && !other.method.IsStatic) { return callType == CallType.ImplicitInstance ? -1 : +1; } else if (!method.IsStatic && other.method.IsStatic) { return callType == CallType.ImplicitInstance ? +1 : -1; } return 0; }
public int CompareEqualParameters(MethodTarget other) { // Prefer normal methods over explicit interface implementations if (other.method.Method.IsPrivate && !this.method.Method.IsPrivate) return +1; if (this.method.Method.IsPrivate && !other.method.Method.IsPrivate) return -1; // Prefer non-generic methods over generic methods if (method.Method.IsGenericMethod) { if (!other.method.Method.IsGenericMethod) { return -1; } else { //!!! Need to support selecting least generic method here return 0; } } else if (other.method.Method.IsGenericMethod) { return +1; } //prefer methods without out params over those with them switch (Compare(returnBuilder.CountOutParams, other.returnBuilder.CountOutParams)) { case 1: return -1; case -1: return 1; } //prefer methods using earlier conversions rules to later ones int maxPriorityThis = FindMaxPriority(this.argBuilders); int maxPriorityOther = FindMaxPriority(other.argBuilders); if (maxPriorityThis < maxPriorityOther) return +1; if (maxPriorityOther < maxPriorityThis) return -1; return 0; }
private void AddTarget(MethodTarget target) { int count = target.ParameterCount; TargetSet set; if (!targetSets.TryGetValue(count, out set)) { set = new TargetSet(this, count); targetSets[count] = set; } set.Add(target); }
private void AddSimpleTarget(MethodTarget target) { AddTarget(target); if (target.method.IsParamsMethod) { ParamsMethodMaker maker = new ParamsMethodMaker(target); paramsMakers.Add(maker); //MethodTarget paramsTarget = maker.MakeTarget(target.ParameterCount - 1); //if (paramsTarget != null) AddTarget(paramsTarget); } }
private static bool IsBest(MethodTarget candidate, List<MethodTarget> applicableTargets, CallType callType) { foreach (MethodTarget target in applicableTargets) { if (candidate == target) continue; if (candidate.CompareTo(target, callType) != +1) return false; } return true; }
/// <summary> /// Constrói a novo instancia do ConfigurationMap para o tipo submetido. /// Isso irá carrega as informações dos metados contidos no tipo para carregar /// o mapeamento do arquivo de configuração <see cref="ConfigurationAttribute"/>. /// </summary> /// <exception cref="GDA.GDAException"></exception> public ConfigurationMap(Type type) { List <MemberAttributeInfo> memberInfos = LoadMembersConfigurationAttributes(Helper.ReflectionFlags.InstanceCriteria, type); foreach (MemberAttributeInfo mai in memberInfos) { ConfigurationAttribute ca = mai.Attributes[0] as ConfigurationAttribute; switch (mai.MemberInfo.MemberType) { case MemberTypes.Method: MethodTarget target = null; if (instanceOverloads.ContainsKey(ca.XmlNodePath)) { target = instanceOverloads[ca.XmlNodePath] as MethodTarget; } if (target != null) { target.AddCallbackMethod(mai.MemberInfo as MethodInfo, ca.RequiredParameters); } else { target = new MethodTarget(ca, mai.MemberInfo as MethodInfo); instanceTargets.Add(target); instanceOverloads[ca.XmlNodePath] = target; } break; case MemberTypes.Field: instanceTargets.Add(new FieldTarget(ca, mai.MemberInfo as FieldInfo)); break; case MemberTypes.Property: instanceTargets.Add(new PropertyTarget(ca, mai.MemberInfo as PropertyInfo)); break; default: throw new GDAException("Unknown configuration target type for member {0} on class {1}.", mai.MemberInfo.Name, type); } } memberInfos = LoadMembersConfigurationAttributes(Helper.ReflectionFlags.StaticCriteria, type); foreach (MemberAttributeInfo mai in memberInfos) { ConfigurationAttribute ca = mai.Attributes[0] as ConfigurationAttribute; switch (mai.MemberInfo.MemberType) { case MemberTypes.Method: MethodTarget target = null; if (staticOverloads.ContainsKey(ca.XmlNodePath)) { target = staticOverloads[ca.XmlNodePath] as MethodTarget; } if (target != null) { target.AddCallbackMethod(mai.MemberInfo as MethodInfo, ca.RequiredParameters); } else { target = new MethodTarget(ca, mai.MemberInfo as MethodInfo); staticTargets.Add(target); staticOverloads[ca.XmlNodePath] = target; } break; case MemberTypes.Field: staticTargets.Add(new FieldTarget(ca, mai.MemberInfo as FieldInfo)); break; case MemberTypes.Property: staticTargets.Add(new PropertyTarget(ca, mai.MemberInfo as PropertyInfo)); break; default: throw new GDAException("Unknown configuration target type for member {0} on class {1}.", mai.MemberInfo.Name, type); } } }
public ParamsMethodMaker(MethodTarget baseTarget) { this.baseTarget = baseTarget; }
// component logic public override void Apply(XmlDocument document, string key) { // XmlNodeList link_nodes = document.SelectNodes("//referenceLink"); XPathNodeIterator linkIterator = document.CreateNavigator().Select(referenceLinkExpression); XPathNavigator[] linkNodes = BuildComponentUtilities.ConvertNodeIteratorToArray(linkIterator); foreach (XPathNavigator linkNode in linkNodes) { // extract link information ReferenceLinkInfo2 link = ReferenceLinkInfo2.Create(linkNode); if (link == null) { WriteMessage(MessageLevel.Warn, "Invalid referenceLink element."); } else { // determine target, link type, and display options string targetId = link.Target; DisplayOptions options = link.DisplayOptions; LinkType2 type = LinkType2.None; Target target = GetTarget(targetId); if (target == null) { // no such target known; set link type to none and warn type = LinkType2.None; WriteMessage(MessageLevel.Warn, String.Format("Unknown reference link target '{0}'.", targetId)); } else { // if overload is prefered and found, change targetId and make link options hide parameters if (link.PreferOverload) { bool isConversionOperator = false; MethodTarget method = target as MethodTarget; if (method != null) { isConversionOperator = method.conversionOperator; } MemberTarget member = target as MemberTarget; // if conversion operator is found, always link to individual topic. if ((member != null) && (!String.IsNullOrEmpty(member.OverloadId)) && !isConversionOperator) { Target overloadTarget = targets[member.OverloadId]; if (overloadTarget != null) { target = overloadTarget; targetId = overloadTarget.Id; } } // if individual conversion operator is found, always display parameters. if (isConversionOperator && member != null && (!string.IsNullOrEmpty(member.OverloadId))) { options = options | DisplayOptions.ShowParameters; } else { options = options & ~DisplayOptions.ShowParameters; } } // get stored link type type = target.DefaultLinkType; // if link type is local or index, determine which if (type == LinkType2.LocalOrIndex) { if ((key != null) && targets.Contains(key) && (target.Container == targets[key].Container)) { type = LinkType2.Local; } else { type = LinkType2.Index; } } } // links to this page are not live if (targetId == key) { type = LinkType2.Self; } else if ((target != null) && (key != null) && targets.Contains(key) && (target.File == targets[key].File)) { type = LinkType2.Self; } // get msdn or external endpoint, if needed string externalUrl = null; if (type == LinkType2.Msdn || type == LinkType2.External) { externalUrl = ResolveExternalUrl(targetId, type); if (String.IsNullOrEmpty(externalUrl)) { type = LinkType2.None; } } // write opening link tag and target info XmlWriter writer = linkNode.InsertAfter(); switch (type) { case LinkType2.None: writer.WriteStartElement("span"); writer.WriteAttributeString("class", "nolink"); break; case LinkType2.Self: writer.WriteStartElement("span"); writer.WriteAttributeString("class", "selflink"); break; case LinkType2.Local: // format link with prefix and/or postfix string href = String.Format(hrefFormat, target.File); // make link relative, if we have a baseUrl if (baseUrl != null) { href = BuildComponentUtilities.GetRelativePath(href, BuildComponentUtilities.EvalXPathExpr(document, baseUrl, "key", key)); } writer.WriteStartElement("a"); writer.WriteAttributeString("href", href); break; case LinkType2.Index: writer.WriteStartElement("mshelp", "link", "http://msdn.microsoft.com/mshelp"); writer.WriteAttributeString("keywords", targetId); writer.WriteAttributeString("tabindex", "0"); break; case LinkType2.Msdn: case LinkType2.External: writer.WriteStartElement("a"); writer.WriteAttributeString("href", externalUrl); writer.WriteAttributeString("target", linkTarget); break; } // write the link text if (String.IsNullOrEmpty(link.DisplayTarget)) { if (link.Contents == null) { if (target != null) { resolver.WriteTarget(target, options, writer); } else { //Console.WriteLine("Attemting to create reference"); Reference reference = TextReferenceUtilities.CreateReference(targetId); //Console.WriteLine("Returned"); if (reference is InvalidReference) { WriteMessage(MessageLevel.Warn, String.Format("Invalid reference link target '{0}'.", targetId)); } resolver.WriteReference(reference, options, writer); } } else { // write contents to writer link.Contents.WriteSubtree(writer); } } else { //Console.WriteLine("Display target = {0}", link.DisplayTarget); if ((String.Compare(link.DisplayTarget, "content", true) == 0) && (link.Contents != null)) { // Use the contents as an XML representation of the display target //Console.WriteLine(link.Contents.NodeType); Reference reference = XmlTargetCollectionUtilities.CreateReference(link.Contents); //Console.WriteLine(reference.GetType().FullName); resolver.WriteReference(reference, options, writer); } if ((String.Compare(link.DisplayTarget, "format", true) == 0) && (link.Contents != null)) { // Use the contents as a format string for the display target string format = link.Contents.OuterXml; //Console.WriteLine("format = {0}", format); string input = null; StringWriter textStore = new StringWriter(); try { XmlWriterSettings settings = new XmlWriterSettings(); settings.ConformanceLevel = ConformanceLevel.Fragment; XmlWriter xmlStore = XmlWriter.Create(textStore, settings); try { if (target != null) { resolver.WriteTarget(target, options, xmlStore); } else { Reference reference = TextReferenceUtilities.CreateReference(targetId); resolver.WriteReference(reference, options, xmlStore); } } finally { xmlStore.Close(); } input = textStore.ToString(); } finally { textStore.Close(); } //Console.WriteLine("input = {0}", input); string output = String.Format(format, input); //Console.WriteLine("output = {0}", output); XmlDocumentFragment fragment = document.CreateDocumentFragment(); fragment.InnerXml = output; fragment.WriteTo(writer); //writer.WriteRaw(output); } else if ((String.Compare(link.DisplayTarget, "extension", true) == 0) && (link.Contents != null)) { Reference extMethodReference = XmlTargetCollectionUtilities.CreateExtensionMethodReference(link.Contents); resolver.WriteReference(extMethodReference, options, writer); } else { // Use the display target value as a CER for the display target TextReferenceUtilities.SetGenericContext(key); Reference reference = TextReferenceUtilities.CreateReference(link.DisplayTarget); //Console.WriteLine("Reference is {0}", reference.GetType().FullName); resolver.WriteReference(reference, options, writer); } } // write the closing link tag writer.WriteEndElement(); writer.Close(); } // delete the original tag linkNode.DeleteSelf(); } }
private void ProcessReferenceLink(XmlDocument document, string key) { XPathNodeIterator linkIterator = document.CreateNavigator().Select( referenceLinkExpression); if (linkIterator == null || linkIterator.Count == 0) { return; } XPathNavigator[] linkNodes = BuildComponentUtilities.ConvertNodeIteratorToArray(linkIterator); foreach (XPathNavigator linkNode in linkNodes) { // extract link information ReferenceLinkInfo link = ReferenceLinkInfo.Create(linkNode); if (link == null) { this.WriteMessage(MessageLevel.Warn, "Invalid referenceLink element."); #if DEBUG this.WriteMessage(MessageLevel.Warn, linkNode.OuterXml); #endif } else { // determine target, link type, and display options string targetId = link.Target; ReferenceLinkDisplayOptions options = link.DisplayOptions; ReferenceLinkType type = ReferenceLinkType.None; Target target = _targets[targetId]; if (target == null) { if (_hasTopicLinks && _targetController[targetId] != null) { this.ProcessConceptualLink(linkNode, key); // delete the original tag linkNode.DeleteSelf(); continue; } else { // no such target known; set link type to none and warn type = ReferenceLinkType.None; this.WriteMessage(MessageLevel.Warn, String.Format( "Unknown reference link target '{0}'.", targetId)); } } else { // if overload is preferred and found, change targetId and make link options hide parameters if (link.PreferOverload) { bool isConversionOperator = false; TargetType targetType = target.TargetType; MemberTarget member = null; if (targetType == TargetType.Method) { MethodTarget method = (MethodTarget)target; isConversionOperator = method.ConversionOperator; member = method; // a method is a member... } else if (targetType == TargetType.Member || targetType == TargetType.Constructor || targetType == TargetType.Procedure || targetType == TargetType.Event || targetType == TargetType.Property) { member = (MemberTarget)target; } // if conversion operator is found, always link to individual topic. if ((member != null) && (!String.IsNullOrEmpty(member.OverloadId)) && !isConversionOperator) { Target overloadTarget = _targets[member.OverloadId]; if (overloadTarget != null) { target = overloadTarget; targetId = overloadTarget.Id; } } // if individual conversion operator is found, always display parameters. if (isConversionOperator && member != null && (!string.IsNullOrEmpty(member.OverloadId))) { options = options | ReferenceLinkDisplayOptions.ShowParameters; } else { options = options & ~ReferenceLinkDisplayOptions.ShowParameters; } } // get stored link type type = _targets.RecentLinkTypeIsMsdn ? _targets.RecentLinkType : target.LinkType; // if link type is local or index, determine which if (type == ReferenceLinkType.LocalOrIndex) { if ((key != null) && _targets.Contains(key) && (target.Container == _targets[key].Container)) { type = ReferenceLinkType.Local; } else { type = ReferenceLinkType.Index; } } } // links to this page are not live if (targetId == key) { type = ReferenceLinkType.Self; } else if ((target != null) && (key != null) && _targets.Contains(key) && (target.File == _targets[key].File)) { type = ReferenceLinkType.Self; } // get msdn endpoint, if needed string msdnUrl = null; if (type == ReferenceLinkType.Msdn) { if ((_msdnResolver == null) || (_msdnResolver.IsDisabled)) { // no msdn resolver } else { msdnUrl = _msdnResolver[targetId]; if (String.IsNullOrEmpty(msdnUrl)) { WriteMessage(MessageLevel.Warn, String.Format( "MSDN URL not found for target '{0}'.", targetId)); } } if (String.IsNullOrEmpty(msdnUrl)) { type = ReferenceLinkType.None; } } // write opening link tag and target info XmlWriter writer = linkNode.InsertAfter(); switch (type) { case ReferenceLinkType.None: writer.WriteStartElement("span"); writer.WriteAttributeString("class", "nolink"); break; case ReferenceLinkType.Self: writer.WriteStartElement("span"); writer.WriteAttributeString("class", "selflink"); break; case ReferenceLinkType.Local: // format link with prefix and/or postfix string href = String.Format(_hrefFormat, target.File); // make link relative, if we have a baseUrl if (_baseUrl != null) { href = BuildComponentUtilities.GetRelativePath(href, BuildComponentUtilities.EvalXPathExpr(document, _baseUrl, "key", key)); } writer.WriteStartElement("a"); writer.WriteAttributeString("href", href); break; case ReferenceLinkType.Index: writer.WriteStartElement("mshelp", "link", "http://msdn.microsoft.com/mshelp"); writer.WriteAttributeString("keywords", targetId); writer.WriteAttributeString("tabindex", "0"); break; case ReferenceLinkType.Msdn: writer.WriteStartElement("a"); writer.WriteAttributeString("href", msdnUrl); writer.WriteAttributeString("target", _linkTarget); break; case ReferenceLinkType.Id: string xhelp = String.Format("ms-xhelp://?Id={0}", targetId); xhelp = xhelp.Replace("#", "%23"); writer.WriteStartElement("a"); writer.WriteAttributeString("href", xhelp); break; } // write the link text if (String.IsNullOrEmpty(link.DisplayTarget)) { if (link.Contents == null) { if (target != null) { _linkResolver.WriteTarget(target, options, writer); } else { Reference reference = ReferenceTextUtilities.CreateReference(targetId); if (reference.ReferenceType == ReferenceType.Invalid) { WriteMessage(MessageLevel.Warn, String.Format( "Invalid reference link target '{0}'.", targetId)); } _linkResolver.WriteReference(reference, options, writer); } } else { // write contents to writer link.Contents.WriteSubtree(writer); } } else { if ((String.Compare(link.DisplayTarget, "content", true) == 0) && (link.Contents != null)) { // Use the contents as an XML representation of the display target Reference reference = TargetCollectionXmlUtilities.CreateReference(link.Contents); _linkResolver.WriteReference(reference, options, writer); } if ((String.Compare(link.DisplayTarget, "format", true) == 0) && (link.Contents != null)) { // Use the contents as a format string for the display target string format = link.Contents.OuterXml; string input = null; StringWriter textStore = new StringWriter(); try { XmlWriter xmlStore = XmlWriter.Create(textStore, _writerSettings); try { if (target != null) { _linkResolver.WriteTarget(target, options, xmlStore); } else { Reference reference = ReferenceTextUtilities.CreateReference(targetId); _linkResolver.WriteReference(reference, options, xmlStore); } } finally { xmlStore.Close(); } input = textStore.ToString(); } finally { textStore.Close(); } string output = String.Format(format, input); XmlDocumentFragment fragment = document.CreateDocumentFragment(); fragment.InnerXml = output; fragment.WriteTo(writer); //writer.WriteRaw(output); } else if ((String.Compare(link.DisplayTarget, "extension", true) == 0) && (link.Contents != null)) { Reference extMethodReference = TargetCollectionXmlUtilities.CreateExtensionMethodReference(link.Contents); _linkResolver.WriteReference(extMethodReference, options, writer); } else { // Use the display target value as a CER for the display target ReferenceTextUtilities.SetGenericContext(key); Reference reference = ReferenceTextUtilities.CreateReference(link.DisplayTarget); _linkResolver.WriteReference(reference, options, writer); } } // write the closing link tag writer.WriteEndElement(); writer.Close(); } // delete the original tag linkNode.DeleteSelf(); } }
public MethodCandidate(MethodCandidate previous, NarrowingLevel narrowingLevel) { this._target = previous.Target; this._parameters = previous._parameters; _narrowingLevel = narrowingLevel; }
public TargetHolder(MethodTarget target) { _target = target; }
public static Target ReadTarget(XmlReader reader) { if (reader == null || reader.NodeType != XmlNodeType.Element) { return(null); } switch (reader.Name) { case "Target": Target target = new Target(); target.ReadXml(reader); return(target); case "NamespaceTarget": NamespaceTarget namespaceTarget = new NamespaceTarget(); namespaceTarget.ReadXml(reader); return(namespaceTarget); case "TypeTarget": TypeTarget typeTarget = new TypeTarget(); typeTarget.ReadXml(reader); return(typeTarget); case "EnumerationTarget": EnumerationTarget enumTarget = new EnumerationTarget(); enumTarget.ReadXml(reader); return(enumTarget); case "MemberTarget": MemberTarget memberTarget = new MemberTarget(); memberTarget.ReadXml(reader); return(memberTarget); case "ConstructorTarget": ConstructorTarget constructorTarget = new ConstructorTarget(); constructorTarget.ReadXml(reader); return(constructorTarget); case "ProcedureTarget": ProcedureTarget procedTarget = new ProcedureTarget(); procedTarget.ReadXml(reader); return(procedTarget); case "EventTarget": EventTarget eventTarget = new EventTarget(); eventTarget.ReadXml(reader); return(eventTarget); case "PropertyTarget": PropertyTarget propertyTarget = new PropertyTarget(); propertyTarget.ReadXml(reader); return(propertyTarget); case "MethodTarget": MethodTarget methodTarget = new MethodTarget(); methodTarget.ReadXml(reader); return(methodTarget); } return(null); }
public void Add(MethodTarget target) { for (int i = 0; i < targets.Count; i++) { if (CompareParameters(targets[i].parameters, target.parameters) == ParameterComparison.Same) { switch (targets[i].CompareEqualParameters(target)) { case -1: // the new method is strictly better than the existing one so remove the existing one targets.RemoveAt(i); i -= 1; // modify the index since we removed a target from the list break; case +1: // the new method is strictly worse than the existing one so skip it return; case 0: // the two methods are identical ignoring CallType so list a conflict hasConflict = true; break; } } } targets.Add(target); }
/// <inheritdoc /> public override void Apply(XmlDocument document, string key) { Target target = null, keyTarget; string msdnUrl = null; foreach (XPathNavigator linkNode in document.CreateNavigator().Select(referenceLinkExpression).ToArray()) { // Extract link information ReferenceLinkInfo link = new ReferenceLinkInfo(linkNode); // Determine target, link type, and display options string targetId = link.Target; DisplayOptions options = link.DisplayOptions; ReferenceLinkType type = ReferenceLinkType.None; if (String.IsNullOrWhiteSpace(targetId)) { this.WriteMessage(key, MessageLevel.Warn, "The target attribute is missing or has no " + "value. You have most likely omitted a cref attribute or left it blank on an XML " + "comments element such as see, seealso, or exception."); continue; } bool targetFound = targets.TryGetValue(targetId, out target, out type); // If it's an overload ID that wasn't found, it's possible that the overloads got excluded. // As such, see if we can find a match for a method using the same ID regardless of any // parameters. if (!targetFound && targetId.StartsWith("Overload:", StringComparison.Ordinal) || targetId.StartsWith("O:", StringComparison.Ordinal)) { string methodTargetId = "M:" + targetId.Substring(targetId.IndexOf(':') + 1); methodTargetId = targets.Keys.FirstOrDefault(k => k.StartsWith(methodTargetId)); if (methodTargetId != null) { targetId = methodTargetId; targetFound = targets.TryGetValue(targetId, out target, out type); options |= DisplayOptions.ShowParameters; // Don't use the content as it may not be appropriate for the method. The default is // "{0} Overload" which no longer applies. Instead we'll show the method name and // its parameters. if (link.DisplayTarget.Equals("format", StringComparison.OrdinalIgnoreCase)) { link.DisplayTarget = null; link.Contents = null; } } } // If not found and it starts with "System." or "Microsoft." we'll go with the assumption that // it's part of a Microsoft class library that is not part of the core framework but does have // documentation available on MSDN. Worst case it doesn't and we get an unresolved link warning // instead of an unknown reference target warning. if (!targetFound && ((targetId.Length > 9 && targetId.Substring(2).StartsWith("System.", StringComparison.Ordinal)) || (targetId.Length > 12 && targetId.Substring(2).StartsWith( "Microsoft.", StringComparison.Ordinal)))) { // Use the same link type as a core framework class targetFound = targets.TryGetValue("T:System.Object", out target, out type); // We don't have a target in this case so links to overloads pages won't work. Also note // that the link text will be generated from the ID which shouldn't make much of a difference // in most cases. If either case is an issue, the Additional Reference Links SHFB plug-in // can be used to generate valid link target data. target = null; } if (!targetFound) { // If not being rendered as a link, don't report a warning if (link.RenderAsLink && targetId != key) { this.WriteMessage(key, MessageLevel.Warn, "Unknown reference link target '{0}'.", targetId); } // !EFW - Turn off the Show Parameters option for unresolved elements except methods. If // not, it outputs an empty "()" after the member name which looks odd. if (targetId[0] != 'M') { options &= ~DisplayOptions.ShowParameters; } } else { // If overload is preferred and found, change targetId and make link options hide parameters if (link.PreferOverload && target != null) { bool isConversionOperator = false; MethodTarget method = target as MethodTarget; if (method != null) { isConversionOperator = method.IsConversionOperator; } MemberTarget member = target as MemberTarget; // If conversion operator is found, always link to individual topic if (member != null && !String.IsNullOrEmpty(member.OverloadId) && !isConversionOperator) { Target overloadTarget = targets[member.OverloadId]; if (overloadTarget != null) { target = overloadTarget; targetId = overloadTarget.Id; } } // If individual conversion operator is found, always display parameters if (isConversionOperator && member != null && !String.IsNullOrEmpty(member.OverloadId)) { options = options | DisplayOptions.ShowParameters; } else { options = options & ~DisplayOptions.ShowParameters; } } } // Suppress the link if so requested. Links to this page are not live. if (!link.RenderAsLink) { type = ReferenceLinkType.None; } else if (targetId == key) { type = ReferenceLinkType.Self; } else if (target != null && targets.TryGetValue(key, out keyTarget) && target.File == keyTarget.File) { type = ReferenceLinkType.Self; } // !EFW - Redirect enumeration fields to the containing enumerated type so that we // get a valid link target. Enum fields don't have a topic to themselves. if (type != ReferenceLinkType.None && type != ReferenceLinkType.Self && type != ReferenceLinkType.Local && targetId.StartsWith("F:", StringComparison.OrdinalIgnoreCase)) { MemberTarget member = target as MemberTarget; if (member != null) { SimpleTypeReference typeRef = member.ContainingType as SimpleTypeReference; if (typeRef != null && targets[typeRef.Id] is EnumerationTarget) { targetId = typeRef.Id; } } } // Get MSDN endpoint if needed if (type == ReferenceLinkType.Msdn) { if (msdnResolver != null && !msdnResolver.IsDisabled) { msdnUrl = msdnResolver.GetMsdnUrl(targetId); if (String.IsNullOrEmpty(msdnUrl)) { // If the web service failed, report the reason if (msdnResolver.IsDisabled) { this.WriteMessage(key, MessageLevel.Warn, "MSDN web service failed. No " + "further look ups will be performed for this build.\r\nReason: {0}", msdnResolver.DisabledReason); } else { this.WriteMessage(key, MessageLevel.Warn, "MSDN URL not found for target '{0}'.", targetId); } type = ReferenceLinkType.None; } } else { type = ReferenceLinkType.None; } } // Write opening link tag and target info XmlWriter writer = linkNode.InsertAfter(); switch (type) { case ReferenceLinkType.None: writer.WriteStartElement("span"); // If the link was intentionally suppressed, write it out as an identifier (i.e. links // in the syntax section). if (link.RenderAsLink) { writer.WriteAttributeString("class", "nolink"); } else { writer.WriteAttributeString("class", "identifier"); } break; case ReferenceLinkType.Self: writer.WriteStartElement("span"); writer.WriteAttributeString("class", "selflink"); break; case ReferenceLinkType.Local: // Format link with prefix and/or postfix string href = String.Format(CultureInfo.InvariantCulture, hrefFormat, target.File); // Make link relative, if we have a baseUrl if (baseUrl != null) { href = href.GetRelativePath(document.EvalXPathExpr(baseUrl, "key", key)); } writer.WriteStartElement("a"); writer.WriteAttributeString("href", href); break; case ReferenceLinkType.Msdn: writer.WriteStartElement("a"); writer.WriteAttributeString("href", msdnUrl); writer.WriteAttributeString("target", linkTarget); break; case ReferenceLinkType.Id: writer.WriteStartElement("a"); writer.WriteAttributeString("href", ("ms-xhelp:///?Id=" + targetId).Replace("#", "%23")); break; } // Write the link text if (String.IsNullOrEmpty(link.DisplayTarget)) { if (link.Contents == null) { if (target != null) { resolver.WriteTarget(target, options, writer); } else { Reference reference = TextReferenceUtilities.CreateReference(targetId); if (reference is InvalidReference) { this.WriteMessage(key, MessageLevel.Warn, "Invalid reference link target '{0}'.", targetId); } resolver.WriteReference(reference, options, writer); } } else { do { link.Contents.WriteSubtree(writer); } while(link.Contents.MoveToNext()); } } else { if (link.DisplayTarget.Equals("content", StringComparison.OrdinalIgnoreCase) && link.Contents != null) { // Use the contents as an XML representation of the display target Reference reference = XmlTargetDictionaryUtilities.CreateReference(link.Contents); resolver.WriteReference(reference, options, writer); } if (link.DisplayTarget.Equals("format", StringComparison.OrdinalIgnoreCase) && link.Contents != null) { // Use the contents as a format string for the display target string format = link.Contents.OuterXml; string input = null; using (StringWriter textStore = new StringWriter(CultureInfo.InvariantCulture)) { XmlWriterSettings settings = new XmlWriterSettings(); settings.ConformanceLevel = ConformanceLevel.Fragment; using (XmlWriter xmlStore = XmlWriter.Create(textStore, settings)) { if (target != null) { resolver.WriteTarget(target, options, xmlStore); } else { Reference reference = TextReferenceUtilities.CreateReference(targetId); resolver.WriteReference(reference, options, xmlStore); } } input = textStore.ToString(); } string output = String.Format(CultureInfo.InvariantCulture, format, input); XmlDocumentFragment fragment = document.CreateDocumentFragment(); fragment.InnerXml = output; fragment.WriteTo(writer); } else if (link.DisplayTarget.Equals("extension", StringComparison.OrdinalIgnoreCase) && link.Contents != null) { Reference extMethodReference = XmlTargetDictionaryUtilities.CreateExtensionMethodReference(link.Contents); resolver.WriteReference(extMethodReference, options, writer); } else { // Use the display target value as a CER for the display target TextReferenceUtilities.SetGenericContext(key); Reference reference = TextReferenceUtilities.CreateReference(link.DisplayTarget); resolver.WriteReference(reference, options, writer); } } // Write the closing link tag writer.WriteEndElement(); writer.Close(); // Delete the original tag linkNode.DeleteSelf(); } }
internal static Candidate CompareEquivalentParameters(MethodTarget one, MethodTarget two) { // Prefer normal methods over explicit interface implementations if (two.Method.IsPrivate && !one.Method.IsPrivate) return Candidate.One; if (one.Method.IsPrivate && !two.Method.IsPrivate) return Candidate.Two; // Prefer non-generic methods over generic methods if (one.Method.IsGenericMethod) { if (!two.Method.IsGenericMethod) { return Candidate.Two; } else { //!!! Need to support selecting least generic method here return Candidate.Equivalent; } } else if (two.Method.IsGenericMethod) { return Candidate.One; } //prefer methods without out params over those with them switch (Compare(one._returnBuilder.CountOutParams, two._returnBuilder.CountOutParams)) { case 1: return Candidate.Two; case -1: return Candidate.One; } //prefer methods using earlier conversions rules to later ones for (int i = Int32.MaxValue; i >= 0; ) { int maxPriorityThis = FindMaxPriority(one._argBuilders, i); int maxPriorityOther = FindMaxPriority(two._argBuilders, i); if (maxPriorityThis < maxPriorityOther) return Candidate.One; if (maxPriorityOther < maxPriorityThis) return Candidate.Two; i = maxPriorityThis - 1; } return Candidate.Equivalent; }