internal ImmutableArray<Symbol> BindCref(CrefSyntax syntax, out Symbol ambiguityWinner, DiagnosticBag diagnostics) { ImmutableArray<Symbol> symbols = BindCrefInternal(syntax, out ambiguityWinner, diagnostics); Debug.Assert(!symbols.IsDefault, "Prefer empty to null."); Debug.Assert((symbols.Length > 1) == ((object)ambiguityWinner != null), "ambiguityWinner should be set iff more than one symbol is returned."); return symbols; }
private ImmutableArray<Symbol> BindCrefInternal(CrefSyntax syntax, out Symbol ambiguityWinner, DiagnosticBag diagnostics) { switch (syntax.Kind()) { case SyntaxKind.TypeCref: return BindTypeCref((TypeCrefSyntax)syntax, out ambiguityWinner, diagnostics); case SyntaxKind.QualifiedCref: return BindQualifiedCref((QualifiedCrefSyntax)syntax, out ambiguityWinner, diagnostics); case SyntaxKind.NameMemberCref: case SyntaxKind.IndexerMemberCref: case SyntaxKind.OperatorMemberCref: case SyntaxKind.ConversionOperatorMemberCref: return BindMemberCref((MemberCrefSyntax)syntax, containerOpt: null, ambiguityWinner: out ambiguityWinner, diagnostics: diagnostics); default: throw ExceptionUtilities.UnexpectedValue(syntax.Kind()); } }
private ImmutableArray<Symbol> BindCrefInternal(CrefSyntax syntax, out Symbol ambiguityWinner, DiagnosticBag diagnostics) { switch (syntax.Kind) { case SyntaxKind.TypeCref: return BindTypeCref((TypeCrefSyntax)syntax, out ambiguityWinner, diagnostics); case SyntaxKind.QualifiedCref: return BindQualifiedCref((QualifiedCrefSyntax)syntax, out ambiguityWinner, diagnostics); case SyntaxKind.NameMemberCref: case SyntaxKind.IndexerMemberCref: case SyntaxKind.OperatorMemberCref: case SyntaxKind.ConversionOperatorMemberCref: return BindMemberCref((MemberCrefSyntax)syntax, containerOpt: null, ambiguityWinner: out ambiguityWinner, diagnostics: diagnostics); default: Debug.Assert(false, "Unexpected cref kind " + syntax.Kind); ambiguityWinner = null; return ImmutableArray<Symbol>.Empty; } }
public static XmlEmptyElementSyntax SeeElement(CrefSyntax cref) { return(EmptyElement("see").AddAttributes(CrefAttribute(cref))); }
/// <summary> /// Bind the cref in the context of the specified location and get semantic information /// such as type, symbols and diagnostics. This method is used to get semantic information about a cref /// that did not actually appear in the source code. /// </summary> /// <param name="position">A character position used to identify a declaration scope and accessibility. This /// character position must be within the FullSpan of the Root syntax node in this SemanticModel. In order to obtain /// the correct scoping rules for the cref, position should be the Start position of the Span of the original cref. /// </param> /// <param name="cref">A syntax node that represents a parsed cref. This syntax node /// need not and typically does not appear in the source code referred to SemanticModel instance.</param> /// <param name="options">SymbolInfo options.</param> /// <returns>The semantic information for the topmost node of the cref.</returns> public SymbolInfo GetSpeculativeSymbolInfo(int position, CrefSyntax cref, SymbolInfoOptions options = SymbolInfoOptions.DefaultOptions) { Debug.Assert(CanGetSemanticInfo(cref, isSpeculative: true)); position = CheckAndAdjustPosition(position); return this.GetCrefSymbolInfo(position, cref, options, HasParameterList(cref)); }
internal static bool HasParameterList(CrefSyntax crefSyntax) { while (crefSyntax.Kind() == SyntaxKind.QualifiedCref) { crefSyntax = ((QualifiedCrefSyntax)crefSyntax).Member; } switch (crefSyntax.Kind()) { case SyntaxKind.NameMemberCref: return ((NameMemberCrefSyntax)crefSyntax).Parameters != null; case SyntaxKind.IndexerMemberCref: return ((IndexerMemberCrefSyntax)crefSyntax).Parameters != null; case SyntaxKind.OperatorMemberCref: return ((OperatorMemberCrefSyntax)crefSyntax).Parameters != null; case SyntaxKind.ConversionOperatorMemberCref: return ((ConversionOperatorMemberCrefSyntax)crefSyntax).Parameters != null; } return false; }
internal static ImmutableArray<Symbol> BindCref(CrefSyntax crefSyntax, Binder binder) { var unusedDiagnostics = DiagnosticBag.GetInstance(); Symbol unusedAmbiguityWinner; var symbols = binder.BindCref(crefSyntax, out unusedAmbiguityWinner, unusedDiagnostics); unusedDiagnostics.Free(); return symbols; }
/// <summary> /// Get a SemanticModel object that is associated with a cref that did not appear in /// this source code. This can be used to get detailed semantic information about sub-parts /// of a cref that did not appear in source code. /// /// NOTE: This will only work in locations where there is already a cref. /// </summary> /// <param name="position">A character position used to identify a declaration scope and accessibility. This /// character position must be within the FullSpan of the Root syntax node in this SemanticModel. /// Furthermore, it must be within the span of an existing cref. /// </param> /// <param name="crefSyntax">A syntax node that represents a parsed cref syntax. /// This node should not be present in the syntax tree associated with this object.</param> /// <param name="speculativeModel">A SemanticModel object that can be used to inquire about the semantic /// information associated with syntax nodes within <paramref name="crefSyntax"/>.</param> /// <returns>Flag indicating whether a speculative semantic model was created.</returns> /// <exception cref="ArgumentException">Throws this exception if the <paramref name="crefSyntax"/> node is contained any SyntaxTree in the current Compilation.</exception> /// <exception cref="ArgumentNullException">Throws this exception if <paramref name="crefSyntax"/> is null.</exception> /// <exception cref="InvalidOperationException">Throws this exception if this model is a speculative semantic model, i.e. <see cref="SemanticModel.IsSpeculativeSemanticModel"/> is true. /// Chaining of speculative semantic model is not supported.</exception> public bool TryGetSpeculativeSemanticModel(int position, CrefSyntax crefSyntax, out SemanticModel speculativeModel) { CheckModelAndSyntaxNodeToSpeculate(crefSyntax); return TryGetSpeculativeSemanticModelCore((SyntaxTreeSemanticModel)this, position, crefSyntax, out speculativeModel); }
public static SpeculativeSyntaxTreeSemanticModel Create(CSharpSemanticModel parentSemanticModel, CrefSyntax root, Binder rootBinder, int position) { return CreateCore(parentSemanticModel, root, rootBinder, position, bindingOption: SpeculativeBindingOption.BindAsTypeOrNamespace); }
internal WithCrefTypeParametersBinder(CrefSyntax crefSyntax, Binder next) : base(next) { _crefSyntax = crefSyntax; }
public override void DefaultVisit(SyntaxNode node) { SyntaxKind nodeKind = node.Kind(); bool diagnose = node.SyntaxTree.ReportDocumentationCommentDiagnostics(); if (nodeKind == SyntaxKind.XmlCrefAttribute) { XmlCrefAttributeSyntax crefAttr = (XmlCrefAttributeSyntax)node; CrefSyntax cref = crefAttr.Cref; BinderFactory factory = _compilation.GetBinderFactory(cref.SyntaxTree); Binder binder = factory.GetBinder(cref); // Do this for the diagnostics, even if it won't be written. DiagnosticBag crefDiagnostics = DiagnosticBag.GetInstance(); string docCommentId = GetDocumentationCommentId(cref, binder, crefDiagnostics); if (diagnose) { _diagnostics.AddRange(crefDiagnostics); } crefDiagnostics.Free(); if (_writer != null) { Visit(crefAttr.Name); VisitToken(crefAttr.EqualsToken); // Not going to visit normally, because we want to skip trivia within // the attribute value. crefAttr.StartQuoteToken.WriteTo(_writer, leading: true, trailing: false); // We're not going to visit the cref because we want to bind it // and write a doc comment ID in its place. _writer.Write(docCommentId); // Not going to visit normally, because we want to skip trivia within // the attribute value. crefAttr.EndQuoteToken.WriteTo(_writer, leading: false, trailing: true); } // Don't descend - we've already written out everything necessary. return; } else if (diagnose && nodeKind == SyntaxKind.XmlNameAttribute) { XmlNameAttributeSyntax nameAttr = (XmlNameAttributeSyntax)node; BinderFactory factory = _compilation.GetBinderFactory(nameAttr.SyntaxTree); Binder binder = factory.GetBinder(nameAttr, nameAttr.Identifier.SpanStart); // Do this for diagnostics, even if we aren't writing. BindName(nameAttr, binder, _memberSymbol, ref _documentedParameters, ref _documentedTypeParameters, _diagnostics); // Do descend - we still need to write out the tokens of the attribute. } // NOTE: if we're recording any include element nodes (i.e. if includeElementsNodes is non-null), // then we want to record all of them, because we won't be able to distinguish in the XML DOM. if (_includeElementNodes != null) { XmlNameSyntax nameSyntax = null; if (nodeKind == SyntaxKind.XmlEmptyElement) { nameSyntax = ((XmlEmptyElementSyntax)node).Name; } else if (nodeKind == SyntaxKind.XmlElementStartTag) { nameSyntax = ((XmlElementStartTagSyntax)node).Name; } if (nameSyntax != null && nameSyntax.Prefix == null && DocumentationCommentXmlNames.ElementEquals(nameSyntax.LocalName.ValueText, DocumentationCommentXmlNames.IncludeElementName)) { _includeElementNodes.Add((CSharpSyntaxNode)node); } } base.DefaultVisit(node); }
public TameCrefSyntax(CrefSyntax node) { Node = node; AddChildren(); }
public static bool TryReduceOrSimplifyExplicitName( this CrefSyntax crefSyntax, SemanticModel semanticModel, out CrefSyntax replacementNode, out TextSpan issueSpan, OptionSet optionSet, CancellationToken cancellationToken) { replacementNode = null; issueSpan = default; // Currently Qualified Cref is the only CrefSyntax We are handling separately if (crefSyntax.Kind() != SyntaxKind.QualifiedCref) { return(false); } var qualifiedCrefSyntax = (QualifiedCrefSyntax)crefSyntax; var memberCref = qualifiedCrefSyntax.Member; // Currently we are dealing with only the NameMemberCrefs if (SimplificationHelpers.PreferPredefinedTypeKeywordInMemberAccess(optionSet, semanticModel.Language) && (memberCref.Kind() == SyntaxKind.NameMemberCref)) { var nameMemberCref = ((NameMemberCrefSyntax)memberCref).Name; var symbolInfo = semanticModel.GetSymbolInfo(nameMemberCref, cancellationToken); var symbol = symbolInfo.Symbol; if (symbol == null) { return(false); } if (symbol is INamespaceOrTypeSymbol namespaceOrTypeSymbol) { // 1. Check for Predefined Types if (symbol is INamedTypeSymbol namedSymbol) { var keywordKind = ExpressionSyntaxExtensions.GetPredefinedKeywordKind(namedSymbol.SpecialType); if (keywordKind != SyntaxKind.None) { replacementNode = SyntaxFactory.TypeCref( SyntaxFactory.PredefinedType( SyntaxFactory.Token(crefSyntax.GetLeadingTrivia(), keywordKind, crefSyntax.GetTrailingTrivia()))); replacementNode = crefSyntax.CopyAnnotationsTo(replacementNode); // we want to show the whole name expression as unnecessary issueSpan = crefSyntax.Span; return(true); } } } } var oldSymbol = semanticModel.GetSymbolInfo(crefSyntax, cancellationToken).Symbol; if (oldSymbol != null) { var speculativeBindingOption = SpeculativeBindingOption.BindAsExpression; if (oldSymbol is INamespaceOrTypeSymbol) { speculativeBindingOption = SpeculativeBindingOption.BindAsTypeOrNamespace; } var newSymbol = semanticModel.GetSpeculativeSymbolInfo(crefSyntax.SpanStart, memberCref, speculativeBindingOption).Symbol; if (newSymbol == oldSymbol) { // Copy Trivia and Annotations memberCref = memberCref.WithLeadingTrivia(crefSyntax.GetLeadingTrivia()); memberCref = crefSyntax.CopyAnnotationsTo(memberCref); issueSpan = qualifiedCrefSyntax.Container.Span; replacementNode = memberCref; return(true); } } return(false); }
internal override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, CrefSyntax crefSyntax, out SemanticModel speculativeModel) { position = CheckAndAdjustPosition(position); Binder binder = GetEnclosingBinder(position); if (binder != null && (binder.Flags.Includes(BinderFlags.Cref) || binder.Flags.Includes(BinderFlags.CrefParameterOrReturnType))) { speculativeModel = SpeculativeSyntaxTreeSemanticModel.Create(parentModel, crefSyntax, binder, position); return true; } speculativeModel = null; return false; }
internal static XmlEmptyElementSyntax SeeTag(CrefSyntax cref) => XmlEmptyElement("see").AddAttributes(XmlCrefAttribute(cref));
/// <summary> /// Given a list of method and/or property candidates, choose the first one (if any) with a signature /// that matches the parameter list in the cref. Return null if there isn't one. /// </summary> /// <remarks> /// Produces a diagnostic for ambiguous matches, but not for unresolved members - WRN_BadXMLRef is /// handled in BindMemberCref. /// </remarks> private static ImmutableArray <Symbol> PerformCrefOverloadResolution(ArrayBuilder <Symbol> candidates, ImmutableArray <ParameterSymbol> parameterSymbols, int arity, MemberCrefSyntax memberSyntax, out Symbol ambiguityWinner, DiagnosticBag diagnostics) { ArrayBuilder <Symbol> viable = null; foreach (Symbol candidate in candidates) { // BREAK: In dev11, any candidate with the type "dynamic" anywhere in its parameter list would be skipped // (see XmlDocCommentBinder::bindXmlReference). Apparently, this was because "the params that the xml doc // comments produce never will." This does not appear to have made sense in dev11 (skipping dropping the // candidate doesn't cause anything to blow up and may cause resolution to start succeeding) and it almost // certainly does not in roslyn (the signature comparer ignores the object-dynamic distinction anyway). Symbol signatureMember; switch (candidate.Kind) { case SymbolKind.Method: { MethodSymbol candidateMethod = (MethodSymbol)candidate; MethodKind candidateMethodKind = candidateMethod.MethodKind; bool candidateMethodIsVararg = candidateMethod.IsVararg; // If the arity from the cref is zero, then we accept methods of any arity. int signatureMemberArity = candidateMethodKind == MethodKind.Constructor ? 0 : (arity == 0 ? candidateMethod.Arity : arity); // CONSIDER: we might want to reuse this method symbol (as long as the MethodKind and Vararg-ness match). signatureMember = new SignatureOnlyMethodSymbol( methodKind: candidateMethodKind, typeParameters: IndexedTypeParameterSymbol.Take(signatureMemberArity), parameters: parameterSymbols, // This specific comparer only looks for varargs. callingConvention: candidateMethodIsVararg ? Microsoft.Cci.CallingConvention.ExtraArguments : Microsoft.Cci.CallingConvention.HasThis, // These are ignored by this specific MemberSignatureComparer. containingType: null, name: null, refKind: RefKind.None, returnType: null, returnTypeCustomModifiers: ImmutableArray <CustomModifier> .Empty, refCustomModifiers: ImmutableArray <CustomModifier> .Empty, explicitInterfaceImplementations: ImmutableArray <MethodSymbol> .Empty); break; } case SymbolKind.Property: { // CONSIDER: we might want to reuse this property symbol. signatureMember = new SignatureOnlyPropertySymbol( parameters: parameterSymbols, // These are ignored by this specific MemberSignatureComparer. containingType: null, name: null, refKind: RefKind.None, type: null, typeCustomModifiers: ImmutableArray <CustomModifier> .Empty, refCustomModifiers: ImmutableArray <CustomModifier> .Empty, isStatic: false, explicitInterfaceImplementations: ImmutableArray <PropertySymbol> .Empty); break; } case SymbolKind.NamedType: // Because we replaced them with constructors when we built the candidate list. throw ExceptionUtilities.UnexpectedValue(candidate.Kind); default: continue; } if (MemberSignatureComparer.CrefComparer.Equals(signatureMember, candidate)) { Debug.Assert(candidate.GetMemberArity() != 0 || candidate.Name == WellKnownMemberNames.InstanceConstructorName || arity == 0, "Can only have a 0-arity, non-constructor candidate if the desired arity is 0."); if (viable == null) { viable = ArrayBuilder <Symbol> .GetInstance(); viable.Add(candidate); } else { bool oldArityIsZero = viable[0].GetMemberArity() == 0; bool newArityIsZero = candidate.GetMemberArity() == 0; // If the cref specified arity 0 and the current candidate has arity 0 but the previous // match did not, then the current candidate is the unambiguous winner (unless there's // another match with arity 0 in a subsequent iteration). if (!oldArityIsZero || newArityIsZero) { if (!oldArityIsZero && newArityIsZero) { viable.Clear(); } viable.Add(candidate); } } } } if (viable == null) { ambiguityWinner = null; return(ImmutableArray <Symbol> .Empty); } if (viable.Count > 1) { ambiguityWinner = viable[0]; CrefSyntax crefSyntax = GetRootCrefSyntax(memberSyntax); diagnostics.Add(ErrorCode.WRN_AmbiguousXMLReference, crefSyntax.Location, crefSyntax.ToString(), ambiguityWinner, viable[1]); } else { ambiguityWinner = null; } return(viable.ToImmutableAndFree()); }
internal sealed override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, CrefSyntax crefSyntax, out SemanticModel speculativeModel) { // crefs can never legally appear within members. speculativeModel = null; return false; }
public static XmlElementSyntax ExceptionElement(CrefSyntax cref, params XmlNodeSyntax[] content) { return ExceptionElement(cref, List(content)); }
public static XmlElementSyntax ExceptionElement(CrefSyntax cref, params XmlNodeSyntax[] content) { return(ExceptionElement(cref, List(content))); }
public static XmlEmptyElementSyntax SeeAlsoElement(CrefSyntax cref) { return EmptyElement("seealso").AddAttributes(CrefAttribute(cref)); }
public static ImmutableArray <Symbol> BindCref(this Microsoft.CodeAnalysis.CSharp.Binder binder, CrefSyntax syntax, out Symbol ambiguityWinner, DiagnosticBag diagnostics) { return(binder.BindCref(syntax, out ambiguityWinner, new Microsoft.CodeAnalysis.CSharp.BindingDiagnosticBag(diagnostics))); }
public static XmlCrefAttributeSyntax CrefAttribute(CrefSyntax cref, SyntaxKind quoteKind) { return XmlCrefAttribute( XmlName("cref"), Token(quoteKind), cref, Token(quoteKind)) .WithLeadingTrivia(Whitespace(" ")); }
public static XmlElementSyntax ExceptionElement(CrefSyntax cref, SyntaxList<XmlNodeSyntax> content) { XmlElementSyntax element = Element("exception", content); return element.WithStartTag(element.StartTag.AddAttributes(CrefAttribute(cref))); }
public static bool TryReduceOrSimplifyExplicitName( this CrefSyntax crefSyntax, SemanticModel semanticModel, out CrefSyntax replacementNode, out TextSpan issueSpan, OptionSet optionSet, CancellationToken cancellationToken) { replacementNode = null; issueSpan = default(TextSpan); // Currently Qualified Cref is the only CrefSyntax We are handling separately if (crefSyntax.Kind() != SyntaxKind.QualifiedCref) { return false; } var qualifiedCrefSyntax = (QualifiedCrefSyntax)crefSyntax; var memberCref = qualifiedCrefSyntax.Member; // Currently we are dealing with only the NameMemberCrefs if (optionSet.GetOption(SimplificationOptions.PreferIntrinsicPredefinedTypeKeywordInMemberAccess, LanguageNames.CSharp) && (memberCref.Kind() == SyntaxKind.NameMemberCref)) { var nameMemberCref = ((NameMemberCrefSyntax)memberCref).Name; var symbolInfo = semanticModel.GetSymbolInfo(nameMemberCref, cancellationToken); var symbol = symbolInfo.Symbol; if (symbol == null) { return false; } if (symbol is INamespaceOrTypeSymbol) { //var namespaceOrTypeSymbol = (INamespaceOrTypeSymbol)symbol; // 1. Check for Predefined Types if (symbol is INamedTypeSymbol) { var namedSymbol = (INamedTypeSymbol)symbol; var keywordKind = ExpressionSyntaxExtensions.GetPredefinedKeywordKind(namedSymbol.SpecialType); if (keywordKind != SyntaxKind.None) { replacementNode = SyntaxFactory.TypeCref( SyntaxFactory.PredefinedType( SyntaxFactory.Token(crefSyntax.GetLeadingTrivia(), keywordKind, crefSyntax.GetTrailingTrivia()))); replacementNode = crefSyntax.CopyAnnotationsTo(replacementNode); // we want to show the whole name expression as unnecessary issueSpan = crefSyntax.Span; return true; } } } } var oldSymbol = semanticModel.GetSymbolInfo(crefSyntax, cancellationToken).Symbol; if (oldSymbol != null) { var speculativeBindingOption = SpeculativeBindingOption.BindAsExpression; if (oldSymbol is INamespaceOrTypeSymbol) { speculativeBindingOption = SpeculativeBindingOption.BindAsTypeOrNamespace; } var newSymbol = semanticModel.GetSpeculativeSymbolInfo(crefSyntax.SpanStart, memberCref, speculativeBindingOption).Symbol; if (newSymbol == oldSymbol) { // Copy Trivia and Annotations memberCref = memberCref.WithLeadingTrivia(crefSyntax.GetLeadingTrivia()); memberCref = crefSyntax.CopyAnnotationsTo(memberCref); issueSpan = qualifiedCrefSyntax.Container.Span; replacementNode = memberCref; return true; } } return false; }
public static XmlCrefAttributeSyntax CrefAttribute(CrefSyntax cref) { return CrefAttribute(cref, SyntaxKind.DoubleQuoteToken); }
/// <summary> /// At this point, we have a list of viable symbols and no parameter list with which to perform /// overload resolution. We'll just return the first symbol, giving a diagnostic if there are /// others. /// Caveat: If there are multiple candidates and only one is from source, then the source symbol /// wins and no diagnostic is reported. /// </summary> private ImmutableArray <Symbol> ProcessParameterlessCrefMemberLookupResults( ImmutableArray <Symbol> symbols, int arity, MemberCrefSyntax memberSyntax, TypeArgumentListSyntax?typeArgumentListSyntax, out Symbol?ambiguityWinner, BindingDiagnosticBag diagnostics) { // If the syntax indicates arity zero, then we match methods of any arity. // However, if there are both generic and non-generic methods, then the // generic methods should be ignored. if (symbols.Length > 1 && arity == 0) { bool hasNonGenericMethod = false; bool hasGenericMethod = false; foreach (Symbol s in symbols) { if (s.Kind != SymbolKind.Method) { continue; } if (((MethodSymbol)s).Arity == 0) { hasNonGenericMethod = true; } else { hasGenericMethod = true; } if (hasGenericMethod && hasNonGenericMethod) { break; //Nothing else to be learned. } } if (hasNonGenericMethod && hasGenericMethod) { symbols = symbols.WhereAsArray(s => s.Kind != SymbolKind.Method || ((MethodSymbol)s).Arity == 0); } } Debug.Assert(!symbols.IsEmpty); Symbol symbol = symbols[0]; // If there's ambiguity, prefer source symbols. // Logic is similar to ResultSymbol, but separate because the error handling is totally different. if (symbols.Length > 1) { // Size is known, but IndexOfSymbolFromCurrentCompilation expects a builder. ArrayBuilder <Symbol> unwrappedSymbols = ArrayBuilder <Symbol> .GetInstance(symbols.Length); foreach (Symbol wrapped in symbols) { unwrappedSymbols.Add(UnwrapAliasNoDiagnostics(wrapped)); } BestSymbolInfo secondBest; BestSymbolInfo best = GetBestSymbolInfo(unwrappedSymbols, out secondBest); Debug.Assert(!best.IsNone); Debug.Assert(!secondBest.IsNone); unwrappedSymbols.Free(); int symbolIndex = 0; if (best.IsFromCompilation) { symbolIndex = best.Index; symbol = symbols[symbolIndex]; // NOTE: symbols, not unwrappedSymbols. } if (symbol.Kind == SymbolKind.TypeParameter) { CrefSyntax crefSyntax = GetRootCrefSyntax(memberSyntax); diagnostics.Add(ErrorCode.WRN_BadXMLRefTypeVar, crefSyntax.Location, crefSyntax.ToString()); } else if (secondBest.IsFromCompilation == best.IsFromCompilation) { CrefSyntax crefSyntax = GetRootCrefSyntax(memberSyntax); int otherIndex = symbolIndex == 0 ? 1 : 0; diagnostics.Add(ErrorCode.WRN_AmbiguousXMLReference, crefSyntax.Location, crefSyntax.ToString(), symbol, symbols[otherIndex]); ambiguityWinner = ConstructWithCrefTypeParameters(arity, typeArgumentListSyntax, symbol); return(symbols.SelectAsArray(sym => ConstructWithCrefTypeParameters(arity, typeArgumentListSyntax, sym))); } } else if (symbol.Kind == SymbolKind.TypeParameter) { CrefSyntax crefSyntax = GetRootCrefSyntax(memberSyntax); diagnostics.Add(ErrorCode.WRN_BadXMLRefTypeVar, crefSyntax.Location, crefSyntax.ToString()); } ambiguityWinner = null; return(ImmutableArray.Create <Symbol>(ConstructWithCrefTypeParameters(arity, typeArgumentListSyntax, symbol))); }
internal abstract bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, CrefSyntax crefSyntax, out SemanticModel speculativeModel);
internal SymbolInfo GetCrefSymbolInfo(int position, CrefSyntax crefSyntax, SymbolInfoOptions options, bool hasParameterList) { var binder = this.GetEnclosingBinder(position); if (binder?.InCref == true) { ImmutableArray<Symbol> symbols = BindCref(crefSyntax, binder); return GetCrefSymbolInfo(symbols, options, hasParameterList); } return SymbolInfo.None; }
private static Symbol GetReferencedSymbol(CrefSyntax crefSyntax, CSharpCompilation compilation, params DiagnosticDescription[] expectedDiagnostics) { Symbol ambiguityWinner; var references = GetReferencedSymbols(crefSyntax, compilation, out ambiguityWinner, expectedDiagnostics); Assert.Null(ambiguityWinner); Assert.InRange(references.Length, 0, 1); //Otherwise, call GetReferencedSymbols return references.FirstOrDefault(); }
/// <summary> /// Gets the semantic information associated with a documentation comment cref. /// </summary> public SymbolInfo GetSymbolInfo(CrefSyntax crefSyntax, CancellationToken cancellationToken = default(CancellationToken)) { CheckSyntaxNode(crefSyntax); return CanGetSemanticInfo(crefSyntax) ? GetSymbolInfoWorker(crefSyntax, SymbolInfoOptions.DefaultOptions, cancellationToken) : SymbolInfo.None; }
private static ImmutableArray<Symbol> GetReferencedSymbols(CrefSyntax crefSyntax, CSharpCompilation compilation, out Symbol ambiguityWinner, params DiagnosticDescription[] expectedDiagnostics) { var binderFactory = compilation.GetBinderFactory(crefSyntax.SyntaxTree); var binder = binderFactory.GetBinder(crefSyntax); DiagnosticBag diagnostics = DiagnosticBag.GetInstance(); var references = binder.BindCref(crefSyntax, out ambiguityWinner, diagnostics); diagnostics.Verify(expectedDiagnostics); diagnostics.Free(); return references; }
public static XmlElementSyntax ExceptionElement(CrefSyntax cref, SyntaxList <XmlNodeSyntax> content) { XmlElementSyntax element = Element("exception", content); return(element.WithStartTag(element.StartTag.AddAttributes(CrefAttribute(cref)))); }
public SymbolInfo GetSymbolInfo(CrefSyntax crefSyntax, CancellationToken cancellationToken = default(CancellationToken)) { return GetSemanticModel(crefSyntax).GetSymbolInfo(crefSyntax, cancellationToken); }
public static XmlEmptyElementSyntax SeeAlsoElement(CrefSyntax cref) { return(EmptyElement(XmlCommentHelper.SeeAlsoXmlTag).AddAttributes(CrefAttribute(cref))); }
/// <summary> /// Bind a CrefSyntax and unwrap the result if it's an alias. /// </summary> /// <remarks> /// Does not respect DocumentationMode, so use a temporary bag if diagnostics are not desired. /// </remarks> private static string GetDocumentationCommentId(CrefSyntax crefSyntax, Binder binder, DiagnosticBag diagnostics) { if (crefSyntax.ContainsDiagnostics) { return ToBadCrefString(crefSyntax); } Symbol ambiguityWinner; ImmutableArray<Symbol> symbols = binder.BindCref(crefSyntax, out ambiguityWinner, diagnostics); Symbol symbol; switch (symbols.Length) { case 0: return ToBadCrefString(crefSyntax); case 1: symbol = symbols[0]; break; default: symbol = ambiguityWinner; Debug.Assert((object)symbol != null); break; } if (symbol.Kind == SymbolKind.Alias) { symbol = ((AliasSymbol)symbol).GetAliasTarget(basesBeingResolved: null); } return symbol.OriginalDefinition.GetDocumentationCommentId(); }
public static XmlCrefAttributeSyntax CrefAttribute(CrefSyntax cref) { return(CrefAttribute(cref, SyntaxKind.DoubleQuoteToken)); }
/// <summary> /// Given a cref syntax that cannot be resolved, get the string that will be written to /// the documentation file in place of a documentation comment ID. /// </summary> private static string ToBadCrefString(CrefSyntax cref) { using (StringWriter tmp = new StringWriter(CultureInfo.InvariantCulture)) { cref.WriteTo(tmp); return "!:" + tmp.ToString().Replace("{", "<").Replace("}", ">"); } }
public static SpeculativeSyntaxTreeSemanticModel Create(SyntaxTreeSemanticModel parentSemanticModel, CrefSyntax root, Binder rootBinder, int position) { return(CreateCore(parentSemanticModel, root, rootBinder, position, bindingOption: SpeculativeBindingOption.BindAsTypeOrNamespace)); }
public static XmlCrefAttributeSyntax CrefAttribute(CrefSyntax cref, SyntaxKind quoteKind) { cref = cref.ReplaceTokens(cref.DescendantTokens(), ReplaceBracketTokens); return SyntaxFactory.XmlCrefAttribute( SyntaxFactory.XmlName(XmlCommentHelper.CrefArgumentName), SyntaxFactory.Token(quoteKind), cref, SyntaxFactory.Token(quoteKind)) .WithLeadingTrivia(SyntaxFactory.Whitespace(" ")); }
internal override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticModel parentModel, int position, CrefSyntax crefSyntax, out SemanticModel speculativeModel) { position = CheckAndAdjustPosition(position); Binder binder = GetEnclosingBinder(position); if (binder?.InCref == true) { speculativeModel = SpeculativeSyntaxTreeSemanticModel.Create(parentModel, crefSyntax, binder, position); return true; } speculativeModel = null; return false; }
public IncompatibleException(ITypeSymbol type, CrefSyntax cref) { Type = type; Syntax = cref; }