public override async Task RegisterCodeFixesAsync(CodeFixContext context) { foreach (Diagnostic?diagnostic in context.Diagnostics) { SemanticModel?semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false); SyntaxNode?syntaxRoot = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); var awaitedExpression = syntaxRoot.FindNode(diagnostic.Location.SourceSpan) as ExpressionSyntax; Task <Document> ApplyFix(bool captureContext) { ExpressionSyntax configuredAwaitExpression = SyntaxFactory.ParenthesizedExpression( SyntaxFactory.InvocationExpression( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.ParenthesizedExpression(awaitedExpression).WithAdditionalAnnotations(Simplifier.Annotation), SyntaxFactory.IdentifierName("ConfigureAwait"))) .AddArgumentListArguments(SyntaxFactory.Argument(SyntaxFactory.LiteralExpression(captureContext ? SyntaxKind.TrueLiteralExpression : SyntaxKind.FalseLiteralExpression)))) .WithAdditionalAnnotations(Simplifier.Annotation); return(Task.FromResult(context.Document.WithSyntaxRoot(syntaxRoot.ReplaceNode(awaitedExpression, configuredAwaitExpression)))); } context.RegisterCodeFix(CodeAction.Create(Strings.VSTHRD111_CodeFix_True_Title, ct => ApplyFix(true), true.ToString()), diagnostic); context.RegisterCodeFix(CodeAction.Create(Strings.VSTHRD111_CodeFix_False_Title, ct => ApplyFix(false), false.ToString()), diagnostic); } }
public void ThrowsArgumentNullException_When_SemanticModelIsNull() { ParameterSyntax parameter = GetNode <ParameterSyntax>("class Test { void Method([Test]int a) { } }"); SemanticModel? semanticModel = null; Assert.Throws <ArgumentNullException>(() => semanticModel !.GetAttribute(parameter, AttributeSymbol)); }
public SymbolDeclaredCompilationEvent(Compilation compilation, ISymbol symbol, SemanticModel?semanticModelWithCachedBoundNodes = null) : base(compilation) { Symbol = symbol; SemanticModelWithCachedBoundNodes = semanticModelWithCachedBoundNodes; _lazyCachedDeclaringReferences = new Lazy <ImmutableArray <SyntaxReference> >(() => symbol.DeclaringSyntaxReferences); }
public NoneOperation(ImmutableArray <IOperation> children, SemanticModel?semanticModel, SyntaxNode syntax, ITypeSymbol?type, ConstantValue?constantValue, bool isImplicit) : base(semanticModel, syntax, isImplicit) { Children = SetParentOperation(children, this); Type = type; OperationConstantValue = constantValue; }
public void ThrowsArgumentNullException_When_SemanticModelIsNull() { TypeParameterSyntax parameter = GetNode <TypeParameterSyntax>("class Test<[Test]T> { }"); SemanticModel? semanticModel = null; Assert.Throws <ArgumentNullException>(() => semanticModel !.GetAllAttributesOfType(parameter, AttributeSymbol)); }
/// <summary> /// Returns a <see cref="CodeAction"/> to be executed. /// </summary> /// <param name="data">Represents data that is used when creating a <see cref="CodeAction"/> for the code fix.</param> protected virtual async Task <CodeAction?> GetCodeActionAsync(CodeFixData <T> data) { if (!data.Success || !data.HasNode) { return(null); } Document document = data.Document; T node = data.Node; CompilationUnitSyntax root = data.Root; Diagnostic diagnostic = data.Diagnostic; SemanticModel? semanticModel = data.SemanticModel ?? await document.GetSemanticModelAsync(data.CancellationToken).ConfigureAwait(false); if (semanticModel is null) { return(null); } return(CodeAction.Create(Title, cancellationToken => ExecuteAsync(CodeFixExecutionContext <T> .From( diagnostic, document, root, node, semanticModel, cancellationToken)), Id)); }
private async Task ProcessDocumentQueueAsync( Document document, HashSet <ISymbol> documentQueue, CancellationToken cancellationToken) { await _progress.OnFindInDocumentStartedAsync(document, cancellationToken).ConfigureAwait(false); SemanticModel?model = null; try { model = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); // start cache for this semantic model FindReferenceCache.Start(model); foreach (var symbol in documentQueue) { await ProcessDocumentAsync(document, model, symbol, cancellationToken).ConfigureAwait(false); } } finally { FindReferenceCache.Stop(model); await _progress.OnFindInDocumentCompletedAsync(document, cancellationToken).ConfigureAwait(false); } }
public void VisitTree(SyntaxNode root, EntryState state, SemanticModel?model, CancellationToken cancellationToken) { if (state == EntryState.Removed) { // mark both syntax *and* transform nodes removed _filterTable.RemoveEntries(); _transformTable.RemoveEntries(); } else { Debug.Assert(model is object); // get the syntax nodes from cache, or a syntax walk using the filter ImmutableArray <SyntaxNode> nodes; if (state != EntryState.Cached || !_filterTable.TryUseCachedEntries(out nodes)) { nodes = IncrementalGeneratorSyntaxWalker.GetFilteredNodes(root, _owner._filterFunc, cancellationToken); _filterTable.AddEntries(nodes, EntryState.Added); } // now, using the obtained syntax nodes, run the transform foreach (var node in nodes) { var value = new GeneratorSyntaxContext(node, model); var transformed = ImmutableArray.Create(_owner._transformFunc(value, cancellationToken)); if (state == EntryState.Added || !_transformTable.TryModifyEntries(transformed, _owner._comparer)) { _transformTable.AddEntries(transformed, EntryState.Added); } } } }
public void ThrowsArgumentNullException_When_SemanticModelIsNull() { IMemberData member = GetClass("class Test { }"); SemanticModel?semanticModel = null; Assert.Throws <ArgumentNullException>(() => semanticModel !.GetAttribute(member.Declaration, AttributeSymbol)); }
/// <summary> /// Check if <paramref name="candidate"/> is a nullcheck. /// </summary> /// <param name="candidate">The <see cref="ExpressionSyntax"/>.</param> /// <param name="semanticModel">The <see cref="SemanticModel"/>. If null only the name is checked.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that cancels the operation.</param> /// <param name="value">The nullchecked value.</param> /// <returns>True if <paramref name="candidate"/> is a nullcheck.</returns> public static bool IsNullCheck(ExpressionSyntax candidate, SemanticModel?semanticModel, CancellationToken cancellationToken, [NotNullWhen(true)] out ExpressionSyntax?value) { if (Equality.IsEqualsCheck(candidate, semanticModel, cancellationToken, out var left, out var right) && IsNullAndExpression(left, right, out value)) { return(true); } switch (candidate) { case IsPatternExpressionSyntax { Expression: { } expression, Pattern : ConstantPatternSyntax { Expression : { } constant } } when constant.IsKind(SyntaxKind.NullLiteralExpression) : value = expression; return(true); case BinaryExpressionSyntax node when node.IsKind(SyntaxKind.CoalesceExpression): value = node.Left; return(true); default: value = null; return(false); }
/// <summary> /// Gets the current semantic model for this document if the model is already computed and still cached. /// In almost all cases, you should call <see cref="GetSemanticModelAsync"/>, which will compute the semantic model /// if necessary. /// </summary> public bool TryGetSemanticModel( [NotNullWhen(returnValue: true)] out SemanticModel?semanticModel ) { semanticModel = null; return(_model != null && _model.TryGetTarget(out semanticModel)); }
public void ThrowsArgumentNullException_When_SemanticModelIsNull() { IMemberData member = GetClass("class Test { }"); SemanticModel?semanticModel = null; Assert.Throws <ArgumentNullException>(() => semanticModel !.GetUsedNamespaces(member.Declaration, Compilation)); }
public LongOperationDelegateType?GetLongOperationDelegateType(InvocationExpressionSyntax?longOperationSetupMethodInvocationNode, SemanticModel?semanticModel, PXContext pxContext, CancellationToken cancellationToken) { if (semanticModel == null) { return(null); } cancellationToken.ThrowIfCancellationRequested(); string?methodName = null; switch (longOperationSetupMethodInvocationNode?.Expression) { case MemberAccessExpressionSyntax memberAccessNode when memberAccessNode.OperatorToken.IsKind(SyntaxKind.DotToken): methodName = memberAccessNode.Name?.Identifier.ValueText; return(GetLongOperationDelegateTypeFromMethodAccessNode(semanticModel, pxContext, memberAccessNode, methodName, cancellationToken)); case MemberBindingExpressionSyntax memberBindingNode when memberBindingNode.OperatorToken.IsKind(SyntaxKind.DotToken): methodName = memberBindingNode.Name?.Identifier.ValueText; return(GetLongOperationDelegateTypeFromMethodAccessNode(semanticModel, pxContext, memberBindingNode, methodName, cancellationToken)); default: return(null); } }
/// <summary> /// Check if <paramref name="candidate"/> is a null check. /// </summary> /// <param name="candidate">The <see cref="ExpressionSyntax"/>.</param> /// <param name="semanticModel">The <see cref="SemanticModel"/>. If null only the name is checked.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that cancels the operation.</param> /// <param name="value">The null checked value.</param> /// <returns>True if <paramref name="candidate"/> is a null check.</returns> public static bool IsNullCheck(ExpressionSyntax candidate, SemanticModel?semanticModel, CancellationToken cancellationToken, [NotNullWhen(true)] out ExpressionSyntax?value) { if (Equality.IsEqualsCheck(candidate, semanticModel, cancellationToken, out var left, out var right) && IsNullAndExpression(left, right, out value)) { #pragma warning disable CS8762 // Parameter must have a non-null value when exiting in some condition. return(true); #pragma warning restore CS8762 // Parameter must have a non-null value when exiting in some condition. } switch (candidate) { case IsPatternExpressionSyntax { Expression: { } expression, Pattern : ConstantPatternSyntax { Expression : { } constant } } when constant.IsKind(SyntaxKind.NullLiteralExpression) : value = expression; return(true); case BinaryExpressionSyntax node when node.IsKind(SyntaxKind.CoalesceExpression): value = node.Left; return(true); default: value = null; return(false); }
public IEnumerable <ITypeSymbol> Process(SyntaxNode node, SemanticModel semantics) { _semantics = semantics ?? throw new ArgumentNullException(nameof(semantics)); _typeNames = new List <ITypeSymbol>(); base.Visit(node); return(_typeNames); }
public void Execute(GeneratorExecutionContext context) { Compilation?compilation = context.Compilation; compilation = GenerateHelperClasses(context); INamedTypeSymbol?serviceLocatorClass = compilation.GetTypeByMetadataName("DI.ServiceLocator") !; INamedTypeSymbol?transientAttribute = compilation.GetTypeByMetadataName("DI.TransientAttribute") !; INamedTypeSymbol?iEnumerableOfT = compilation.GetTypeByMetadataName("System.Collections.Generic.IEnumerable`1") !.ConstructUnboundGenericType(); INamedTypeSymbol?listOfT = compilation.GetTypeByMetadataName("System.Collections.Generic.List`1") !; var knownTypes = new KnownTypes(iEnumerableOfT, listOfT, transientAttribute); var services = new List <Service>(); foreach (SyntaxTree?tree in compilation.SyntaxTrees) { SemanticModel?semanticModel = compilation.GetSemanticModel(tree); IEnumerable <INamedTypeSymbol>?typesToCreate = from i in tree.GetRoot().DescendantNodesAndSelf().OfType <InvocationExpressionSyntax>() let symbol = semanticModel.GetSymbolInfo(i).Symbol as IMethodSymbol where symbol != null where SymbolEqualityComparer.Default.Equals(symbol.ContainingType, serviceLocatorClass) select symbol.ReturnType as INamedTypeSymbol; foreach (INamedTypeSymbol?typeToCreate in typesToCreate) { CollectServices(context, typeToCreate, compilation, services, knownTypes); } } GenerateServiceLocator(context, services); }
public override async Task RegisterCodeFixesAsync(CodeFixContext context) { // Get the syntax root and semantic model Document doc = context.Document; SyntaxNode?root = await doc.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); SemanticModel?model = await doc.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false); if (root == null || model == null) { return; } // Nothing to do if the GeneratedDllImportAttribute is not in the compilation INamedTypeSymbol?generatedDllImportAttrType = model.Compilation.GetTypeByMetadataName(TypeNames.GeneratedDllImportAttribute); if (generatedDllImportAttrType == null) { return; } INamedTypeSymbol?dllImportAttrType = model.Compilation.GetTypeByMetadataName(typeof(DllImportAttribute).FullName); if (dllImportAttrType == null) { return; } // Get the syntax node tied to the diagnostic and check that it is a method declaration if (root.FindNode(context.Span) is not MethodDeclarationSyntax methodSyntax) { return; } if (model.GetDeclaredSymbol(methodSyntax, context.CancellationToken) is not IMethodSymbol methodSymbol) { return; } // Make sure the method has the DllImportAttribute if (!TryGetAttribute(methodSymbol, dllImportAttrType, out AttributeData? dllImportAttr)) { return; } // Register code fix context.RegisterCodeFix( CodeAction.Create( Resources.ConvertToGeneratedDllImport, cancelToken => ConvertToGeneratedDllImport( context.Document, methodSyntax, methodSymbol, dllImportAttr !, generatedDllImportAttrType, cancelToken), equivalenceKey: ConvertToGeneratedDllImportKey), context.Diagnostics); }
protected abstract void AddReplacements( SemanticModel?semanticModel, SyntaxNode root, ImmutableArray <TextSpan> spans, Workspace workspace, ConcurrentDictionary <SyntaxToken, SyntaxToken> replacements, CancellationToken cancellationToken );
/// <summary> /// Check if <paramref name="candidate"/> is a check for equality. /// Operators == and != /// Equals, ReferenceEquals. /// </summary> /// <param name="candidate">The <see cref="InvocationExpressionSyntax"/>.</param> /// <param name="semanticModel">The <see cref="SemanticModel"/>. If null only the name is checked.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that cancels the operation.</param> /// <param name="left">The left value.</param> /// <param name="right">The right value.</param> /// <returns>True if <paramref name="candidate"/> is a check for equality.</returns> public static bool IsObjectEquals(InvocationExpressionSyntax candidate, SemanticModel?semanticModel, CancellationToken cancellationToken, [NotNullWhen(true)] out ExpressionSyntax?left, [NotNullWhen(true)] out ExpressionSyntax?right) { if (candidate is null) { throw new ArgumentNullException(nameof(candidate)); } if (candidate.ArgumentList is { Arguments : { Count : 2 } arguments } &&
public InvalidOperation(ImmutableArray <IOperation> children, SemanticModel?semanticModel, SyntaxNode syntax, ITypeSymbol?type, ConstantValue?constantValue, bool isImplicit) : base(semanticModel, syntax, isImplicit) { // we don't allow null children. Debug.Assert(children.All(o => o != null)); Children = SetParentOperation(children, this); Type = type; OperationConstantValue = constantValue; }
public SortOrder(MemberDeclarationSyntax member, SemanticModel?semanticModel) { _declarationOrder = new Lazy <DeclarationOrder?>(() => GetDeclarationOrder(member)); _visibilityOrder = new Lazy <VisibilityOrder?>(() => GetVisibilityOrder(member)); _staticOrder = new Lazy <StaticOrder?>(() => GetStaticOrder(member)); _interfaceOrder = new Lazy <int?>(() => semanticModel != null ? GetInterfaceOrder(member, semanticModel) : null); _interfaceOrderName = new Lazy <string?>(() => GetInterfaceOrderName(member, semanticModel)); }
static INamedTypeSymbol?GetReceiverType( SyntaxNode receiverSyntax, SemanticModel?model, CancellationToken cancellationToken) { var typeInfo = model?.GetTypeInfo(receiverSyntax, cancellationToken); return(typeInfo?.Type as INamedTypeSymbol); }
internal override bool TryGetSpeculativeSemanticModelForMethodBodyCore( SyntaxTreeSemanticModel parentModel, int position, AccessorDeclarationSyntax accessor, out SemanticModel?speculativeModel ) { speculativeModel = null; return(false); }
protected override void AddReplacements( SemanticModel?semanticModel, SyntaxNode root, ImmutableArray <TextSpan> spans, ConcurrentDictionary <SyntaxToken, SyntaxToken> replacements, CancellationToken cancellationToken) { // C# doesn't support case correction since we are a case sensitive language. return; }
#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters private static ImmutableArray <SymbolDisplayPart> ToDisplayParts( ITypeSymbol symbol, CodeAnalysis.NullableFlowState nullableFlowState, SemanticModel?semanticModelOpt, int positionOpt, SymbolDisplayFormat format, bool minimal) { return(ToDisplayParts(symbol.WithNullableAnnotation(nullableFlowState.ToAnnotation()), semanticModelOpt, positionOpt, format, minimal)); }
public void VisitWithModel(SemanticModel model, SyntaxNode node) { Debug.Assert( _semanticModel is null && model is not null && model.SyntaxTree == node.SyntaxTree ); _semanticModel = model; Visit(node); _semanticModel = null; }
internal override bool TryGetSpeculativeSemanticModelCore( SyntaxTreeSemanticModel parentModel, int position, ArrowExpressionClauseSyntax expressionBody, out SemanticModel?speculativeModel ) { speculativeModel = null; return(false); }
internal override bool TryGetSpeculativeSemanticModelCore( SyntaxTreeSemanticModel parentModel, int position, StatementSyntax statement, out SemanticModel?speculativeModel ) { speculativeModel = null; return(false); }
public static bool NodeHasConstantValueNull(SyntaxNode?node, SemanticModel?model) { if (node == null || model == null) { return(false); } Optional <object> value = model.GetConstantValue(node); return(value.HasValue && value.Value == null); }
internal override bool TryGetSpeculativeSemanticModelCore( SyntaxTreeSemanticModel parentModel, int position, EqualsValueClauseSyntax initializer, out SemanticModel?speculativeModel ) { speculativeModel = null; return(false); }