/// <summary> /// Parses a <see cref="StackFrameNameNode"/> which could either be a <see cref="StackFrameSimpleNameNode"/> or <see cref="StackFrameQualifiedNameNode" />. /// /// Nodes will be parsed for arity but not generic type arguments. /// /// <code> /// All of the following are valid nodes, where "$$" marks the parsing starting point, and "[|" + "|]" mark the endpoints of the parsed node excluding trivia /// * [|$$MyNamespace.MyClass.MyMethod|](string s) /// * MyClass.MyMethod([|$$string|] s) /// * MyClass.MyMethod([|$$string[]|] s) /// * [|$$MyClass`1.MyMethod|](string s) /// * [|$$MyClass.MyMethod|][T](T t) /// </code> /// /// </summary> private StackFrameNameNode?TryParseRequiredNameNode(bool scanAtTrivia) { var currentIdentifer = _lexer.TryScanIdentifier(scanAtTrivia: scanAtTrivia, scanLeadingWhitespace: true, scanTrailingWhitespace: false); if (!currentIdentifer.HasValue) { return(null); } var(success, genericIdentifier) = TryScanGenericTypeIdentifier(currentIdentifer.Value); if (!success) { return(null); } RoslynDebug.AssertNotNull(genericIdentifier); StackFrameNameNode nameNode = genericIdentifier; while (true) { (success, var memberAccess) = TryParseQualifiedName(nameNode); if (!success) { return(null); } if (memberAccess is null) { Debug.Assert(nameNode is StackFrameQualifiedNameNode or StackFrameSimpleNameNode); return(nameNode); } nameNode = memberAccess; } }
internal static ImmutableArray <PortableExecutableReference> ResolveMetadataReference(CommandLineReference cmdReference, MetadataReferenceResolver metadataResolver, List <DiagnosticInfo>?diagnosticsOpt, CommonMessageProvider?messageProviderOpt) { RoslynDebug.Assert(metadataResolver != null); Debug.Assert((diagnosticsOpt == null) == (messageProviderOpt == null)); ImmutableArray <PortableExecutableReference> references; try { references = metadataResolver.ResolveReference(cmdReference.Reference, baseFilePath: null, properties: cmdReference.Properties); } catch (Exception e) when(diagnosticsOpt != null && (e is BadImageFormatException || e is IOException)) { var diagnostic = PortableExecutableReference.ExceptionToDiagnostic(e, messageProviderOpt !, Location.None, cmdReference.Reference, cmdReference.Properties.Kind); diagnosticsOpt.Add(((DiagnosticWithInfo)diagnostic).Info); return(ImmutableArray <PortableExecutableReference> .Empty); } if (references.IsDefaultOrEmpty && diagnosticsOpt != null) { RoslynDebug.AssertNotNull(messageProviderOpt); diagnosticsOpt.Add(new DiagnosticInfo(messageProviderOpt, messageProviderOpt.ERR_MetadataFileNotFound, cmdReference.Reference)); return(ImmutableArray <PortableExecutableReference> .Empty); } return(references); }
public MethodDebugInfo( ImmutableArray <HoistedLocalScopeRecord> hoistedLocalScopeRecords, ImmutableArray <ImmutableArray <ImportRecord> > importRecordGroups, ImmutableArray <ExternAliasRecord> externAliasRecords, ImmutableDictionary <int, ImmutableArray <bool> >?dynamicLocalMap, ImmutableDictionary <int, ImmutableArray <string?> >?tupleLocalMap, string defaultNamespaceName, ImmutableArray <string> localVariableNames, ImmutableArray <TLocalSymbol> localConstants, ILSpan reuseSpan) { RoslynDebug.Assert(!importRecordGroups.IsDefault); RoslynDebug.Assert(!externAliasRecords.IsDefault); RoslynDebug.AssertNotNull(defaultNamespaceName); HoistedLocalScopeRecords = hoistedLocalScopeRecords; ImportRecordGroups = importRecordGroups; ExternAliasRecords = externAliasRecords; DynamicLocalMap = dynamicLocalMap; TupleLocalMap = tupleLocalMap; DefaultNamespaceName = defaultNamespaceName; LocalVariableNames = localVariableNames; LocalConstants = localConstants; ReuseSpan = reuseSpan; }
public void AnalyzeCodeBlock(CodeBlockAnalysisContext context) { if (_analyzer.IsIgnoredCodeBlock(context.CodeBlock)) { return; } var(completed, intervalTree) = _codeBlockIntervals.GetOrAdd(context.CodeBlock.SyntaxTree, _ => (new StrongBox <bool>(false), SimpleIntervalTree.Create(new TextSpanIntervalIntrospector(), Array.Empty <TextSpan>()))); if (completed.Value) { return; } RoslynDebug.AssertNotNull(intervalTree); lock (completed) { if (completed.Value) { return; } if (intervalTree.HasIntervalThatOverlapsWith(context.CodeBlock.FullSpan.Start, context.CodeBlock.FullSpan.End)) { return; } intervalTree.AddIntervalInPlace(context.CodeBlock.FullSpan); } _analyzer.AnalyzeCodeBlock(context); }
public void TestPreviewDiagnostic() { var hostServices = EditorTestCompositions.EditorFeatures.GetHostServices(); var diagnosticService = (IDiagnosticUpdateSource)((IMefHostExportProvider)hostServices).GetExportedValue <IDiagnosticAnalyzerService>(); RoslynDebug.AssertNotNull(diagnosticService); var taskSource = new TaskCompletionSource <DiagnosticsUpdatedArgs>(); diagnosticService.DiagnosticsUpdated += (s, a) => taskSource.TrySetResult(a); using var previewWorkspace = new PreviewWorkspace(hostServices); var solution = previewWorkspace.CurrentSolution .WithAnalyzerReferences(new[] { DiagnosticExtensions.GetCompilerDiagnosticAnalyzerReference(LanguageNames.CSharp) }) .AddProject("project", "project.dll", LanguageNames.CSharp) .AddDocument("document", "class { }") .Project .Solution; Assert.True(previewWorkspace.TryApplyChanges(solution)); previewWorkspace.OpenDocument(previewWorkspace.CurrentSolution.Projects.First().DocumentIds[0]); previewWorkspace.EnableDiagnostic(); // wait 20 seconds taskSource.Task.Wait(20000); Assert.True(taskSource.Task.IsCompleted); var args = taskSource.Task.Result; Assert.True(args.Diagnostics.Length > 0); }
private void ReportDiagnosticsIfNeeded(NameColonSyntax nameColon, SyntaxNodeAnalysisContext context, AnalyzerOptions options, SyntaxTree syntaxTree, CancellationToken cancellationToken) { if (!nameColon.Parent.IsKind(SyntaxKind.Argument, out ArgumentSyntax? argument)) { return; } var parseOptions = (CSharpParseOptions)syntaxTree.Options; var preference = options.GetOption( CodeStyleOptions.PreferInferredTupleNames, context.Compilation.Language, syntaxTree, cancellationToken); if (!preference.Value || !CSharpInferredMemberNameReducer.CanSimplifyTupleElementName(argument, parseOptions)) { return; } // Create a normal diagnostic context.ReportDiagnostic( DiagnosticHelper.Create( Descriptor, nameColon.GetLocation(), preference.Notification.Severity, additionalLocations: null, properties: null)); // Also fade out the part of the name-colon syntax RoslynDebug.AssertNotNull(UnnecessaryWithoutSuggestionDescriptor); var fadeSpan = TextSpan.FromBounds(nameColon.Name.SpanStart, nameColon.ColonToken.Span.End); context.ReportDiagnostic( Diagnostic.Create( UnnecessaryWithoutSuggestionDescriptor, syntaxTree.GetLocation(fadeSpan))); }
private void TrackBulkFileOperations() { RoslynDebug.AssertNotNull(_workspace); // we will pause whatever ambient work loads we have that are tied to IGlobalOperationNotificationService // such as solution crawler, pre-emptive remote host synchronization and etc. any background work users didn't // explicitly asked for. // // this should give all resources to BulkFileOperation. we do same for things like build, // debugging, wait dialog and etc. BulkFileOperation is used for things like git branch switching and etc. var globalNotificationService = _workspace.Services.GetRequiredService <IGlobalOperationNotificationService>(); // BulkFileOperation can't have nested events. there will be ever only 1 events (Begin/End) // so we only need simple tracking. var gate = new object(); IDisposable?localRegistration = null; BulkFileOperation.Begin += (s, a) => StartBulkFileOperationNotification(); BulkFileOperation.End += (s, a) => StopBulkFileOperationNotification(); return; void StartBulkFileOperationNotification() { RoslynDebug.Assert(gate != null); RoslynDebug.Assert(globalNotificationService != null); lock (gate) { // this shouldn't happen, but we are using external component // so guarding us from them if (localRegistration != null) { FatalError.ReportAndCatch(new InvalidOperationException("BulkFileOperation already exist"), ErrorSeverity.General); return; } localRegistration = globalNotificationService.Start("BulkFileOperation"); } } void StopBulkFileOperationNotification() { RoslynDebug.Assert(gate != null); lock (gate) { // this can happen if BulkFileOperation was already in the middle // of running. to make things simpler, decide to not use IsInProgress // which we need to worry about race case. if (localRegistration == null) { return; } localRegistration.Dispose(); localRegistration = null; } } }
public override async Task InitializeAsync() { await base.InitializeAsync().ConfigureAwait(true); if (_solutionName != null) { RoslynDebug.AssertNotNull(_projectTemplate); await TestServices.SolutionExplorer.CreateSolutionAsync(_solutionName, HangMitigatingCancellationToken); await TestServices.SolutionExplorer.AddProjectAsync(ProjectName, _projectTemplate, LanguageName, HangMitigatingCancellationToken); await TestServices.SolutionExplorer.RestoreNuGetPackagesAsync(ProjectName, HangMitigatingCancellationToken); // Winforms and XAML do not open text files on creation // so these editor tasks will not work if that is the project template being used. if (_projectTemplate is not WellKnownProjectTemplates.WinFormsApplication and not WellKnownProjectTemplates.WpfApplication and not WellKnownProjectTemplates.CSharpNetCoreClassLibrary and not WellKnownProjectTemplates.VisualBasicNetCoreClassLibrary) { await TestServices.Editor.SetUseSuggestionModeAsync(false, HangMitigatingCancellationToken); await ClearEditorAsync(HangMitigatingCancellationToken); } } }
public static bool TryRead(string filterFilename, PathResolver pathResolver, [NotNullWhen(true)] out string?solutionFilename, out ImmutableHashSet <string> projectFilter) { try { using var document = JsonDocument.Parse(File.ReadAllText(filterFilename)); var solution = document.RootElement.GetProperty("solution"); // Convert directory separators to the platform's default, since that is what MSBuild provide us. var solutionPath = solution.GetProperty("path").GetString()?.Replace('\\', Path.DirectorySeparatorChar); if (solutionPath is null || Path.GetDirectoryName(filterFilename) is not string baseDirectory) { solutionFilename = string.Empty; projectFilter = ImmutableHashSet <string> .Empty; return(false); } if (!pathResolver.TryGetAbsoluteSolutionPath(solutionPath, baseDirectory, DiagnosticReportingMode.Throw, out solutionFilename)) { // TryGetAbsoluteSolutionPath should throw before we get here. solutionFilename = string.Empty; projectFilter = ImmutableHashSet <string> .Empty; return(false); } if (!File.Exists(solutionFilename)) { projectFilter = ImmutableHashSet <string> .Empty; return(false); } // The base directory for projects is the solution folder. baseDirectory = Path.GetDirectoryName(solutionFilename) !; RoslynDebug.AssertNotNull(baseDirectory); var filterProjects = ImmutableHashSet.CreateBuilder <string>(StringComparer.OrdinalIgnoreCase); foreach (var project in solution.GetProperty("projects").EnumerateArray()) { // Convert directory separators to the platform's default, since that is what MSBuild provide us. var projectPath = project.GetString()?.Replace('\\', Path.DirectorySeparatorChar); if (projectPath is null) { continue; } // Fill the filter with the absolute project paths. if (pathResolver.TryGetAbsoluteProjectPath(projectPath, baseDirectory, DiagnosticReportingMode.Throw, out var absoluteProjectPath)) { filterProjects.Add(absoluteProjectPath); } } projectFilter = filterProjects.ToImmutable(); return(true); } catch { solutionFilename = string.Empty; projectFilter = ImmutableHashSet <string> .Empty; return(false); } }
private static TypeSymbol DecodeTupleTypesInternal(TypeSymbol metadataType, ImmutableArray <string?> elementNames, bool hasTupleElementNamesAttribute) { RoslynDebug.AssertNotNull(metadataType); var decoder = new TupleTypeDecoder(elementNames); try { var decoded = decoder.DecodeType(metadataType); // If not all of the names have been used, the metadata is bad if (!hasTupleElementNamesAttribute || decoder._namesIndex == 0) { return(decoded); } } catch (InvalidOperationException) { // Indicates that the tuple info in the attribute didn't match // the type. Bad metadata. } if (metadataType.HasUseSiteError) { return(metadataType); } // Bad metadata return(new UnsupportedMetadataTypeSymbol()); }
private static TypeSymbol DecodeTupleTypesInternal( TypeSymbol metadataType, ImmutableArray <string?> elementNames, bool hasTupleElementNamesAttribute ) { RoslynDebug.AssertNotNull(metadataType); var decoder = new TupleTypeDecoder(elementNames); var decoded = decoder.DecodeType(metadataType); if (!decoder._decodingFailed) { if (!hasTupleElementNamesAttribute || decoder._namesIndex == 0) { return(decoded); } } // If not all of the names have been used, the metadata is bad if (decoder._foundUsableErrorType) { return(metadataType); } // Bad metadata return(new UnsupportedMetadataTypeSymbol()); }
public void SerializeSourceText( SerializableSourceText text, ObjectWriter writer, SolutionReplicationContext context, CancellationToken cancellationToken ) { cancellationToken.ThrowIfCancellationRequested(); if (text.Storage is not null) { context.AddResource(text.Storage); writer.WriteInt32((int)text.Storage.ChecksumAlgorithm); writer.WriteEncoding(text.Storage.Encoding); writer.WriteInt32((int)SerializationKinds.MemoryMapFile); writer.WriteString(text.Storage.Name); writer.WriteInt64(text.Storage.Offset); writer.WriteInt64(text.Storage.Size); } else { RoslynDebug.AssertNotNull(text.Text); writer.WriteInt32((int)text.Text.ChecksumAlgorithm); writer.WriteEncoding(text.Text.Encoding); writer.WriteInt32((int)SerializationKinds.Bits); text.Text.WriteTo(writer, cancellationToken); } }
internal sealed override void DecodeWellKnownAttribute(ref DecodeWellKnownAttributeArguments <AttributeSyntax, CSharpAttributeData, AttributeLocation> arguments) { var attribute = arguments.Attribute; Debug.Assert(!attribute.HasErrors); Debug.Assert(arguments.SymbolPart == AttributeLocation.None); if (attribute.IsTargetAttribute(this, AttributeDescription.SpecialNameAttribute)) { arguments.GetOrCreateData <CommonEventWellKnownAttributeData>().HasSpecialNameAttribute = true; } else if (attribute.IsTargetAttribute(this, AttributeDescription.NullableAttribute)) { // NullableAttribute should not be set explicitly. RoslynDebug.AssertNotNull(arguments.AttributeSyntaxOpt); arguments.Diagnostics.Add(ErrorCode.ERR_ExplicitNullableAttribute, arguments.AttributeSyntaxOpt.Location); } else if (attribute.IsTargetAttribute(this, AttributeDescription.ExcludeFromCodeCoverageAttribute)) { arguments.GetOrCreateData <CommonEventWellKnownAttributeData>().HasExcludeFromCodeCoverageAttribute = true; } else if (attribute.IsTargetAttribute(this, AttributeDescription.TupleElementNamesAttribute)) { RoslynDebug.AssertNotNull(arguments.AttributeSyntaxOpt); arguments.Diagnostics.Add(ErrorCode.ERR_ExplicitTupleElementNamesAttribute, arguments.AttributeSyntaxOpt.Location); } else if (attribute.IsTargetAttribute(this, AttributeDescription.SkipLocalsInitAttribute)) { CSharpAttributeData.DecodeSkipLocalsInitAttribute <CommonEventWellKnownAttributeData>(DeclaringCompilation, ref arguments); } }
private void OnWorkspaceChanged(object?sender, WorkspaceChangeEventArgs e) { if (e.Kind == WorkspaceChangeKind.ProjectChanged) { RoslynDebug.AssertNotNull(e.ProjectId); var oldProject = e.OldSolution.GetRequiredProject(e.ProjectId); var newProject = e.NewSolution.GetRequiredProject(e.ProjectId); if (!object.Equals(oldProject.ParseOptions, newProject.ParseOptions)) { var workspace = e.NewSolution.Workspace; var documentId = workspace.GetDocumentIdInCurrentContext( SubjectBuffer.AsTextContainer() ); if (documentId != null) { var relatedDocumentIds = e.NewSolution.GetRelatedDocumentIds( documentId ); if (relatedDocumentIds.Any(d => d.ProjectId == e.ProjectId)) { RaiseChanged(); } } } } }
protected void AddBraceSuppressOperations(List <SuppressOperation> list, SyntaxNode node) { var bracePair = node.GetBracePair(); if (!bracePair.IsValidBracePair()) { return; } var firstTokenOfNode = node.GetFirstToken(includeZeroWidth: true); if (node is MemberDeclarationSyntax memberDeclNode) { (firstTokenOfNode, _) = memberDeclNode.GetFirstAndLastMemberDeclarationTokensAfterAttributes(); } if (node.IsLambdaBodyBlock()) { RoslynDebug.AssertNotNull(node.Parent); // include lambda itself. firstTokenOfNode = node.Parent.GetFirstToken(includeZeroWidth: true); } else if (node.IsKind(SyntaxKind.PropertyPatternClause)) { // include the pattern recursive pattern syntax and/or subpattern firstTokenOfNode = firstTokenOfNode.GetPreviousToken(); } // suppress wrapping on whole construct that owns braces and also brace pair itself if // it is on same line AddSuppressWrappingIfOnSingleLineOperation(list, firstTokenOfNode, bracePair.closeBrace); AddSuppressWrappingIfOnSingleLineOperation(list, bracePair.openBrace, bracePair.closeBrace); }
public void CompleteFromTask(Task <T> task) { // As an optimization, we'll cancel the request even we did get a value for it. // That way things abort sooner. if (task.IsCanceled || _cancellationToken.IsCancellationRequested) { Cancel(); } else if (task.IsFaulted) { // TrySetException wraps its argument in an AggregateException, so we pass the inner exceptions from // the antecedent to avoid wrapping in two layers of AggregateException. RoslynDebug.AssertNotNull(task.Exception); if (task.Exception.InnerExceptions.Count > 0) { this.TrySetException(task.Exception.InnerExceptions); } else { this.TrySetException(task.Exception); } } else { this.TrySetResult(task.Result); } _cancellationTokenRegistration.Dispose(); }
private static SyntaxNode?GetTopContainingNode([DisallowNull] SyntaxNode?node) { RoslynDebug.AssertNotNull(node.Parent); node = node.Parent; if (!IsSpecialContainingNode(node)) { return(node); } var lastSpecialContainingNode = node; node = node.Parent; while (node != null) { if (!IsSpecialContainingNode(node)) { return(lastSpecialContainingNode); } lastSpecialContainingNode = node; node = node.Parent; } return(null); }
private static async Task <Solution> FixAllInDocumentAsync(Document document, ImmutableArray <Diagnostic> diagnostics, CodeActionOptionsProvider options, CancellationToken cancellationToken) { // All the target namespaces should be the same for a given document Debug.Assert(diagnostics.Select(diagnostic => diagnostic.Properties[MatchFolderAndNamespaceConstants.TargetNamespace]).Distinct().Count() == 1); var targetNamespace = diagnostics.First().Properties[MatchFolderAndNamespaceConstants.TargetNamespace]; RoslynDebug.AssertNotNull(targetNamespace); // Use the Renamer.RenameDocumentAsync API to sync namespaces in the document. This allows // us to keep in line with the sync methodology that we have as a public API and not have // to rewrite or move the complex logic. RenameDocumentAsync is designed to behave the same // as the intent of this analyzer/codefix pair. var targetFolders = PathMetadataUtilities.BuildFoldersFromNamespace(targetNamespace, document.Project.DefaultNamespace); var documentWithInvalidFolders = document.WithFolders(document.Folders.Concat("Force-Namespace-Change")); var renameActionSet = await Renamer.RenameDocumentAsync( documentWithInvalidFolders, new DocumentRenameOptions(), #if !CODE_STYLE options, #endif documentWithInvalidFolders.Name, newDocumentFolders : targetFolders, cancellationToken : cancellationToken).ConfigureAwait(false); var newSolution = await renameActionSet.UpdateSolutionAsync(documentWithInvalidFolders.Project.Solution, cancellationToken).ConfigureAwait(false); Debug.Assert(newSolution != document.Project.Solution); return(newSolution); }
private void ReportDiagnosticsIfNeeded(NameEqualsSyntax nameEquals, SyntaxNodeAnalysisContext context, AnalyzerOptions options, SyntaxTree syntaxTree, CancellationToken cancellationToken) { if (!nameEquals.Parent.IsKind(SyntaxKind.AnonymousObjectMemberDeclarator, out AnonymousObjectMemberDeclaratorSyntax? anonCtor)) { return; } var preference = options.GetOption( CodeStyleOptions.PreferInferredAnonymousTypeMemberNames, context.Compilation.Language, syntaxTree, cancellationToken); if (!preference.Value || !CSharpInferredMemberNameReducer.CanSimplifyAnonymousTypeMemberName(anonCtor)) { return; } // Create a normal diagnostic context.ReportDiagnostic( DiagnosticHelper.Create( Descriptor, nameEquals.GetLocation(), preference.Notification.Severity, additionalLocations: null, properties: null)); // Also fade out the part of the name-equals syntax RoslynDebug.AssertNotNull(UnnecessaryWithoutSuggestionDescriptor); var fadeSpan = TextSpan.FromBounds(nameEquals.Name.SpanStart, nameEquals.EqualsToken.Span.End); context.ReportDiagnostic( Diagnostic.Create( UnnecessaryWithoutSuggestionDescriptor, syntaxTree.GetLocation(fadeSpan))); }
/// <summary> /// Construct a body for a method containing a call to a single other method with the same signature (modulo name). /// </summary> /// <param name="F">Bound node factory.</param> /// <param name="methodToInvoke">Method to invoke in constructed body.</param> /// <param name="useBaseReference">True for "base.", false for "this.".</param> /// <returns>Body for implementedMethod.</returns> internal static BoundBlock ConstructSingleInvocationMethodBody( SyntheticBoundNodeFactory F, MethodSymbol methodToInvoke, bool useBaseReference ) { var argBuilder = ArrayBuilder <BoundExpression> .GetInstance(); RoslynDebug.AssertNotNull(F.CurrentFunction); foreach (var param in F.CurrentFunction.Parameters) { argBuilder.Add(F.Parameter(param)); } BoundExpression invocation = F.Call( useBaseReference ? (BoundExpression)F.Base(baseType: methodToInvoke.ContainingType) : F.This(), methodToInvoke, argBuilder.ToImmutableAndFree() ); return(F.CurrentFunction.ReturnsVoid ? F.Block(F.ExpressionStatement(invocation), F.Return()) : F.Block(F.Return(invocation))); }
public DirectiveStack Add(Directive directive) { switch (directive.Kind) { case SyntaxKind.EndIfDirectiveTrivia: var prevIf = GetPreviousIf(_directives); if (prevIf == null || !prevIf.Any()) { goto default; // no matching if directive !! leave directive alone } RoslynDebug.AssertNotNull(_directives); // If 'prevIf' isn't null, then '_directives' wasn't null. return(new DirectiveStack(CompleteIf(_directives, out _))); case SyntaxKind.EndRegionDirectiveTrivia: var prevRegion = GetPreviousRegion(_directives); if (prevRegion == null || !prevRegion.Any()) { goto default; // no matching region directive !! leave directive alone } RoslynDebug.AssertNotNull(_directives); // If 'prevRegion' isn't null, then '_directives' wasn't null. return(new DirectiveStack(CompleteRegion(_directives))); // remove region directives from stack but leave everything else default: return(new DirectiveStack(new ConsList <Directive>(directive, _directives ?? ConsList <Directive> .Empty))); } }
/// <returns>The tracking span of the inserted "/**/" if there is an $end$ location, null /// otherwise.</returns> protected override ITrackingSpan?InsertEmptyCommentAndGetEndPositionTrackingSpan() { RoslynDebug.AssertNotNull(ExpansionSession); var endSpanInSurfaceBuffer = new VsTextSpan[1]; if (ExpansionSession.GetEndSpan(endSpanInSurfaceBuffer) != VSConstants.S_OK) { return(null); } if (!TryGetSubjectBufferSpan(endSpanInSurfaceBuffer[0], out var subjectBufferEndSpan)) { return(null); } var endPosition = subjectBufferEndSpan.Start.Position; var commentString = "/**/"; SubjectBuffer.Insert(endPosition, commentString); var commentSpan = new Span(endPosition, commentString.Length); return(SubjectBuffer.CurrentSnapshot.CreateTrackingSpan(commentSpan, SpanTrackingMode.EdgeExclusive)); }
/// <inheritdoc/> public async Task <Solution> SyncNamespacesAsync( ImmutableArray <Project> projects, CodeActionOptionsProvider options, CancellationToken cancellationToken) { // all projects must be of the same language Debug.Assert(projects.All(project => project.Language == projects[0].Language)); var solution = projects[0].Solution; var diagnosticAnalyzers = ImmutableArray.Create <DiagnosticAnalyzer>(DiagnosticAnalyzer); var diagnosticsByProject = await GetDiagnosticsByProjectAsync(projects, diagnosticAnalyzers, cancellationToken).ConfigureAwait(false); // If no diagnostics are reported, then there is nothing to fix. if (diagnosticsByProject.Values.All(diagnostics => diagnostics.IsEmpty)) { return(solution); } var fixAllContext = await GetFixAllContextAsync(solution, CodeFixProvider, diagnosticsByProject, options, cancellationToken).ConfigureAwait(false); var fixAllProvider = CodeFixProvider.GetFixAllProvider(); RoslynDebug.AssertNotNull(fixAllProvider); return(await ApplyCodeFixAsync(fixAllProvider, fixAllContext, cancellationToken).ConfigureAwait(false)); }
public async Task TestGlobalImports() { // Make sure no glyph is in the margin at first. await TestServices.InheritanceMargin.DisableOptionsAsync(LanguageName, HangMitigatingCancellationToken); await TestServices.SolutionExplorer.OpenFileAsync( ProjectName, "Class1.cs", HangMitigatingCancellationToken); await TestServices.InheritanceMargin.EnableOptionsAndEnsureGlyphsAppearAsync(LanguageName, 1, HangMitigatingCancellationToken); await TestServices.InheritanceMargin.ClickTheGlyphOnLine(1, HangMitigatingCancellationToken); // Move focus to menu item 'System' await TestServices.Input.SendWithoutActivateAsync(VirtualKeyCode.TAB); // Navigate to 'System' await TestServices.Input.SendWithoutActivateAsync(VirtualKeyCode.RETURN); await TestServices.Workspace.WaitForAllAsyncOperationsAsync(new[] { FeatureAttribute.InheritanceMargin }, HangMitigatingCancellationToken); await TestServices.EditorVerifier.TextContainsAsync(@"global using global::System;$$", assertCaretPosition : true); var document = await TestServices.Editor.GetActiveDocumentAsync(HangMitigatingCancellationToken); RoslynDebug.AssertNotNull(document); Assert.NotEqual(WorkspaceKind.MetadataAsSource, document.Project.Solution.Workspace.Kind); }
public override BoundNode VisitWithExpression(BoundWithExpression withExpr) { RoslynDebug.AssertNotNull(withExpr.CloneMethod); Debug.Assert(withExpr.CloneMethod.ParameterCount == 0); Debug.Assert(withExpr.Receiver.Type !.Equals(withExpr.Type, TypeCompareKind.ConsiderEverything)); // for a with expression of the form // // receiver with { P1 = e1, P2 = e2 } // // we want to lower it to a call to the receiver's `Clone` method, then // set the given record properties. i.e. // // var tmp = (ReceiverType)receiver.Clone(); // tmp.P1 = e1; // tmp.P2 = e2; // tmp var cloneCall = _factory.Convert( withExpr.Type, _factory.Call( VisitExpression(withExpr.Receiver), withExpr.CloneMethod)); return(MakeExpressionWithInitializer( withExpr.Syntax, cloneCall, withExpr.InitializerExpression, withExpr.Type)); }
/// <summary> /// Initializes a new instance of the <see cref="ImmutableHashMap<TKey, TValue>.ListBucket"/> class. /// </summary> /// <param name="buckets">The buckets.</param> internal ListBucket(ValueBucket[] buckets) : base(buckets[0].Hash) { RoslynDebug.AssertNotNull(buckets); Debug.Assert(buckets.Length >= 2); _buckets = buckets; }
private async Task <Document> CleanupCoreAsync( Document document, ImmutableArray <TextSpan> spans, CancellationToken cancellationToken ) { RoslynDebug.AssertNotNull(_syntaxDelegatee); var root = await document .GetRequiredSyntaxRootAsync(cancellationToken) .ConfigureAwait(false); var newRoot = _syntaxDelegatee( root, spans, document.Project.Solution.Workspace, cancellationToken ); if (root != newRoot) { return(document.WithSyntaxRoot(newRoot)); } return(document); }
/// <summary> /// Initializes a new instance of the <see cref="ImmutableHashMap<TKey, TValue>.HashBucket"/> class. /// </summary> /// <param name="suggestedHashRoll">The suggested hash roll.</param> /// <param name="bucket1">The bucket1.</param> /// <param name="bucket2">The bucket2.</param> internal HashBucket(int suggestedHashRoll, ValueOrListBucket bucket1, ValueOrListBucket bucket2) { RoslynDebug.AssertNotNull(bucket1); RoslynDebug.AssertNotNull(bucket2); Debug.Assert(bucket1.Hash != bucket2.Hash); // find next hashRoll that causes these two to be slotted in different buckets var h1 = bucket1.Hash; var h2 = bucket2.Hash; int s1; int s2; for (var i = 0; i < 32; i++) { _hashRoll = (suggestedHashRoll + i) & 31; s1 = this.ComputeLogicalSlot(h1); s2 = this.ComputeLogicalSlot(h2); if (s1 != s2) { _count = 2; _used = (1u << s1) | (1u << s2); _buckets = new Bucket[2]; _buckets[this.ComputePhysicalSlot(s1)] = bucket1; _buckets[this.ComputePhysicalSlot(s2)] = bucket2; return; } } throw new InvalidOperationException(); }
protected static void ValidateAndReportDiagnostic( SyntaxNodeAnalysisContext context, int numberOfPlaceholderArguments, string formatString, int formatStringPosition) { // removing escaped left brackets and replacing with space characters so they won't // impede the extraction of placeholders, yet the locations of the placeholders are // the same as in the original string. var formatStringWithEscapedBracketsChangedToSpaces = RemoveEscapedBrackets(formatString); var matches = s_extractPlaceholdersRegex.Matches(formatStringWithEscapedBracketsChangedToSpaces); foreach (Match?match in matches) { RoslynDebug.AssertNotNull(match); var textInsideBrackets = match.Groups[1].Value; if (!PlaceholderIndexIsValid(textInsideBrackets, numberOfPlaceholderArguments)) { var invalidPlaceholderText = "{" + textInsideBrackets + "}"; var invalidPlaceholderLocation = Location.Create( context.Node.SyntaxTree, new Text.TextSpan( formatStringPosition + match.Index, invalidPlaceholderText.Length)); var diagnostic = Diagnostic.Create( Rule, invalidPlaceholderLocation, invalidPlaceholderText); context.ReportDiagnostic(diagnostic); } } }
/// <summary> /// Calculate the set of changes up to top-level types. The result /// will be used as a filter when traversing the module. /// /// Note that these changes only include user-defined source symbols, not synthesized symbols since those will be /// generated during lowering of the changed user-defined symbols. /// </summary> private static void CalculateChanges(IEnumerable <SemanticEdit> edits, out IReadOnlyDictionary <ISymbol, SymbolChange> changes, out ISet <ISymbol> replaceSymbols) { var changesBuilder = new Dictionary <ISymbol, SymbolChange>(); HashSet <ISymbol>?lazyReplaceSymbolsBuilder = null; foreach (var edit in edits) { SymbolChange change; switch (edit.Kind) { case SemanticEditKind.Update: change = SymbolChange.Updated; break; case SemanticEditKind.Insert: change = SymbolChange.Added; break; case SemanticEditKind.Replace: Debug.Assert(edit.NewSymbol != null); (lazyReplaceSymbolsBuilder ??= new HashSet <ISymbol>()).Add(edit.NewSymbol); change = SymbolChange.Added; break; case SemanticEditKind.Delete: // No work to do. continue; default: throw ExceptionUtilities.UnexpectedValue(edit.Kind); } var member = edit.NewSymbol; RoslynDebug.AssertNotNull(member); // Partial methods are supplied as implementations but recorded // internally as definitions since definitions are used in emit. if (member.Kind == SymbolKind.Method) { var method = (IMethodSymbol)member; // Partial methods should be implementations, not definitions. Debug.Assert(method.PartialImplementationPart == null); Debug.Assert((edit.OldSymbol == null) || (((IMethodSymbol)edit.OldSymbol).PartialImplementationPart == null)); var definitionPart = method.PartialDefinitionPart; if (definitionPart != null) { member = definitionPart; } } AddContainingTypesAndNamespaces(changesBuilder, member); changesBuilder.Add(member, change); } changes = changesBuilder; replaceSymbols = lazyReplaceSymbolsBuilder ?? SpecializedCollections.EmptySet <ISymbol>(); }