예제 #1
0
            internal void ApplyConflictResolutionEdits(IInlineRenameReplacementInfo conflictResolution, LinkedFileMergeSessionResult mergeResult, IEnumerable <Document> documents, CancellationToken cancellationToken)
            {
                _session._threadingContext.ThrowIfNotOnUIThread();

                if (!AreAllReferenceSpansMappable())
                {
                    // don't dynamically update the reference spans for documents with unmappable projections
                    return;
                }

                using (new SelectionTracking(this))
                {
                    // 1. Undo any previous edits and update the buffer to resulting document after conflict resolution
                    _session.UndoManager.UndoTemporaryEdits(_subjectBuffer, disconnect: false);

                    var newDocument      = mergeResult.MergedSolution.GetDocument(documents.First().Id);
                    var originalDocument = _baseDocuments.Single(d => d.Id == newDocument.Id);

                    var changes = GetTextChangesFromTextDifferencingServiceAsync(originalDocument, newDocument, cancellationToken).WaitAndGetResult(cancellationToken);

                    // TODO: why does the following line stop responding when uncommented?
                    // newDocument.GetTextChangesAsync(this.baseDocuments.Single(d => d.Id == newDocument.Id), cancellationToken).WaitAndGetResult(cancellationToken).Reverse();

                    _session.UndoManager.CreateConflictResolutionUndoTransaction(_subjectBuffer, () =>
                    {
                        using var edit = _subjectBuffer.CreateEdit(EditOptions.DefaultMinimalChange, null, s_propagateSpansEditTag);

                        foreach (var change in changes)
                        {
                            edit.Replace(change.Span.Start, change.Span.Length, change.NewText);
                        }

                        edit.ApplyAndLogExceptions();
                    });

                    // 2. We want to update referenceSpanToLinkedRenameSpanMap where spans were affected by conflict resolution.
                    // We also need to add the remaining document edits to conflictResolutionRenameTrackingSpans
                    // so they get classified/tagged correctly in the editor.
                    _conflictResolutionRenameTrackingSpans.Clear();

                    var documentReplacements = documents
                                               .Select(document => (document, conflictResolution.GetReplacements(document.Id).Where(r => GetRenameSpanKind(r.Kind) != RenameSpanKind.None).ToImmutableArray()))
                                               .ToImmutableArray();

                    var firstDocumentReplacements     = documentReplacements.FirstOrDefault(d => !d.Item2.IsEmpty);
                    var bufferContainsLinkedDocuments = documentReplacements.Length > 1 && firstDocumentReplacements.document != null;
                    var linkedDocumentsMightConflict  = bufferContainsLinkedDocuments;
                    if (linkedDocumentsMightConflict)
                    {
                        // When changes are made and linked documents are involved, some of the linked documents may
                        // have changes that differ from others. When these changes conflict (both differ and overlap),
                        // the inline rename UI reveals the conflicts. However, the merge process for finding these
                        // conflicts is slow, so we want to avoid it when possible. This code block attempts to set
                        // linkedDocumentsMightConflict back to false, eliminating the need to merge the changes as part
                        // of the conflict detection process. Currently we only special case one scenario: ignoring
                        // documents that have no changes at all, we check if all linked documents have exactly the same
                        // set of changes.

                        // 1. Check if all documents have the same replacement spans (or no replacements)
                        var spansMatch = true;
                        foreach (var(document, replacements) in documentReplacements)
                        {
                            if (document == firstDocumentReplacements.document || replacements.IsEmpty)
                            {
                                continue;
                            }

                            if (replacements.Length != firstDocumentReplacements.Item2.Length)
                            {
                                spansMatch = false;
                                break;
                            }

                            for (var i = 0; i < replacements.Length; i++)
                            {
                                if (!replacements[i].Equals(firstDocumentReplacements.Item2[i]))
                                {
                                    spansMatch = false;
                                    break;
                                }
                            }

                            if (!spansMatch)
                            {
                                break;
                            }
                        }

                        // 2. If spans match, check content
                        if (spansMatch)
                        {
                            linkedDocumentsMightConflict = false;

                            // Only need to check the new span's content
                            var firstDocumentNewText     = conflictResolution.NewSolution.GetDocument(firstDocumentReplacements.document.Id).GetTextAsync(cancellationToken).WaitAndGetResult(cancellationToken);
                            var firstDocumentNewSpanText = firstDocumentReplacements.Item2.SelectAsArray(replacement => firstDocumentNewText.ToString(replacement.NewSpan));
                            foreach (var(document, replacements) in documentReplacements)
                            {
                                if (document == firstDocumentReplacements.document || replacements.IsEmpty)
                                {
                                    continue;
                                }

                                var documentNewText = conflictResolution.NewSolution.GetDocument(document.Id).GetTextAsync(cancellationToken).WaitAndGetResult(cancellationToken);
                                for (var i = 0; i < replacements.Length; i++)
                                {
                                    if (documentNewText.ToString(replacements[i].NewSpan) != firstDocumentNewSpanText[i])
                                    {
                                        // Have to use the slower merge process
                                        linkedDocumentsMightConflict = true;
                                        break;
                                    }
                                }

                                if (linkedDocumentsMightConflict)
                                {
                                    break;
                                }
                            }
                        }
                    }

                    foreach (var document in documents)
                    {
                        var relevantReplacements = conflictResolution.GetReplacements(document.Id).Where(r => GetRenameSpanKind(r.Kind) != RenameSpanKind.None);
                        if (!relevantReplacements.Any())
                        {
                            continue;
                        }

                        var mergedReplacements = linkedDocumentsMightConflict
                            ? GetMergedReplacementInfos(
                            relevantReplacements,
                            conflictResolution.NewSolution.GetDocument(document.Id),
                            mergeResult.MergedSolution.GetDocument(document.Id),
                            cancellationToken)
                            : relevantReplacements;

                        // Show merge conflicts comments as unresolvable conflicts, and do not
                        // show any other rename-related spans that overlap a merge conflict comment.
                        var mergeConflictComments = mergeResult.MergeConflictCommentSpans.ContainsKey(document.Id)
                            ? mergeResult.MergeConflictCommentSpans[document.Id]
                            : SpecializedCollections.EmptyEnumerable <TextSpan>();

                        foreach (var conflict in mergeConflictComments)
                        {
                            // TODO: Add these to the unresolvable conflict counts in the dashboard

                            _conflictResolutionRenameTrackingSpans.Add(new RenameTrackingSpan(
                                                                           _subjectBuffer.CurrentSnapshot.CreateTrackingSpan(conflict.ToSpan(), SpanTrackingMode.EdgeInclusive, TrackingFidelityMode.Forward),
                                                                           RenameSpanKind.UnresolvedConflict));
                        }

                        foreach (var replacement in mergedReplacements)
                        {
                            var kind = GetRenameSpanKind(replacement.Kind);

                            if (_referenceSpanToLinkedRenameSpanMap.ContainsKey(replacement.OriginalSpan) && kind != RenameSpanKind.Complexified)
                            {
                                var linkedRenameSpan = _session._renameInfo.GetConflictEditSpan(
                                    new InlineRenameLocation(newDocument, replacement.NewSpan), GetTriggerText(newDocument, replacement.NewSpan),
                                    GetWithoutAttributeSuffix(_session.ReplacementText,
                                                              document.GetLanguageService <LanguageServices.ISyntaxFactsService>().IsCaseSensitive), cancellationToken);

                                if (linkedRenameSpan.HasValue)
                                {
                                    if (!mergeConflictComments.Any(s => replacement.NewSpan.IntersectsWith(s)))
                                    {
                                        _referenceSpanToLinkedRenameSpanMap[replacement.OriginalSpan] = new RenameTrackingSpan(
                                            _subjectBuffer.CurrentSnapshot.CreateTrackingSpan(
                                                linkedRenameSpan.Value.ToSpan(),
                                                SpanTrackingMode.EdgeInclusive,
                                                TrackingFidelityMode.Forward),
                                            kind);
                                    }
                                }
                                else
                                {
                                    // We might not have a renameable span if an alias conflict completely changed the text
                                    _referenceSpanToLinkedRenameSpanMap[replacement.OriginalSpan] = new RenameTrackingSpan(
                                        _referenceSpanToLinkedRenameSpanMap[replacement.OriginalSpan].TrackingSpan,
                                        RenameSpanKind.None);

                                    if (_activeSpan.HasValue && _activeSpan.Value.IntersectsWith(replacement.OriginalSpan))
                                    {
                                        _activeSpan = null;
                                    }
                                }
                            }
                            else
                            {
                                if (!mergeConflictComments.Any(s => replacement.NewSpan.IntersectsWith(s)))
                                {
                                    _conflictResolutionRenameTrackingSpans.Add(new RenameTrackingSpan(
                                                                                   _subjectBuffer.CurrentSnapshot.CreateTrackingSpan(replacement.NewSpan.ToSpan(), SpanTrackingMode.EdgeInclusive, TrackingFidelityMode.Forward),
                                                                                   kind));
                                }
                            }
                        }

                        if (!linkedDocumentsMightConflict)
                        {
                            break;
                        }
                    }

                    UpdateReadOnlyRegions();

                    // 3. Reset the undo state and notify the taggers.
                    this.ApplyReplacementText(updateSelection: false);
                    RaiseSpansChanged();
                }
            }
예제 #2
0
 IEnumerable <Cci.ICustomAttribute> Cci.IReference.GetAttributes(EmitContext context)
 {
     return(SpecializedCollections.EmptyEnumerable <Cci.ICustomAttribute>());
 }
예제 #3
0
 internal void FindReferences(ITextSnapshot snapshot, int caretPosition)
 {
     _waitIndicator.Wait(
         title: EditorFeaturesResources.FindReferences,
         message: EditorFeaturesResources.FindingReferences,
         action: context =>
     {
         Document document = snapshot.GetOpenDocumentInCurrentContextWithChanges();
         if (document != null)
         {
             var service = document.Project.LanguageServices.GetService <IFindReferencesService>();
             if (service != null)
             {
                 using (Logger.LogBlock(FunctionId.CommandHandler_FindAllReference, context.CancellationToken))
                 {
                     if (!service.TryFindReferences(document, caretPosition, context))
                     {
                         foreach (var presenter in _presenters)
                         {
                             presenter.DisplayResult(document.Project.Solution, SpecializedCollections.EmptyEnumerable <ReferencedSymbol>());
                             return;
                         }
                     }
                 }
             }
         }
     }, allowCancel: true);
 }
            private async Task <Solution> UpdateProjectsAsync(Solution solution, HashSet <Checksum> oldChecksums, HashSet <Checksum> newChecksums)
            {
                var oldMap = await GetProjectMapAsync(solution, oldChecksums).ConfigureAwait(false);

                var newMap = await GetProjectMapAsync(_assetProvider, newChecksums).ConfigureAwait(false);

                // bulk sync assets
                await SynchronizeAssetsAsync(oldMap, newMap).ConfigureAwait(false);

                // added project
                foreach (var(projectId, newProjectChecksums) in newMap)
                {
                    if (!oldMap.ContainsKey(projectId))
                    {
                        var projectInfo = await _assetProvider.CreateProjectInfoAsync(newProjectChecksums.Checksum, _cancellationToken).ConfigureAwait(false);

                        if (projectInfo == null)
                        {
                            // this project is not supported in OOP
                            continue;
                        }

                        // we have new project added
                        solution = solution.AddProject(projectInfo);
                    }
                }

                // remove all project references from projects that changed. this ensures exceptions will not occur for
                // cyclic references during an incremental update.
                foreach (var(projectId, newProjectChecksums) in newMap)
                {
                    if (!oldMap.TryGetValue(projectId, out var oldProjectChecksums))
                    {
                        continue;
                    }

                    if (oldProjectChecksums.ProjectReferences.Checksum != newProjectChecksums.ProjectReferences.Checksum)
                    {
                        solution = solution.WithProjectReferences(projectId, SpecializedCollections.EmptyEnumerable <ProjectReference>());
                    }
                }

                // removed project
                foreach (var(projectId, _) in oldMap)
                {
                    if (!newMap.ContainsKey(projectId))
                    {
                        // we have a project removed
                        solution = solution.RemoveProject(projectId);
                    }
                }

                // changed project
                foreach (var(projectId, newProjectChecksums) in newMap)
                {
                    if (!oldMap.TryGetValue(projectId, out var oldProjectChecksums))
                    {
                        continue;
                    }

                    Contract.ThrowIfTrue(oldProjectChecksums.Checksum == newProjectChecksums.Checksum);

                    solution = await UpdateProjectAsync(solution.GetProject(projectId) !, oldProjectChecksums, newProjectChecksums).ConfigureAwait(false);
                }

                return(solution);
            }
        internal override CommonPEModuleBuilder CreateModuleBuilder(EmitOptions emitOptions, IMethodSymbol debugEntryPoint, Stream sourceLinkStream, IEnumerable <EmbeddedText> embeddedTexts, IEnumerable <ResourceDescription> manifestResources, CompilationTestData testData, DiagnosticBag diagnostics, CancellationToken cancellationToken)
        {
            Debug.Assert(!IsSubmission || HasCodeToEmit());

            var runtimeMDVersion = GetRuntimeMetadataVersion(emitOptions, diagnostics);

            if (runtimeMDVersion == null)
            {
                Debug.Assert(runtimeMDVersion != null, "Set PhpCommandLineArguments.EmitOptions");
                return(null);
            }

            var moduleProps = ConstructModuleSerializationProperties(emitOptions, runtimeMDVersion);

            if (manifestResources == null)
            {
                manifestResources = SpecializedCollections.EmptyEnumerable <ResourceDescription>();
            }

            if (SynthesizedResources != null)
            {
                manifestResources = manifestResources.Concat(SynthesizedResources);
            }

            manifestResources = manifestResources.Concat(new[] { SourceMetadataResource() });

            PEModuleBuilder moduleBeingBuilt;

            if (_options.OutputKind.IsNetModule())
            {
                moduleBeingBuilt = new PENetModuleBuilder(
                    this,
                    SourceModule,
                    emitOptions,
                    moduleProps,
                    manifestResources);
            }
            else
            {
                var kind = _options.OutputKind.IsValid() ? _options.OutputKind : OutputKind.DynamicallyLinkedLibrary;
                moduleBeingBuilt = new PEAssemblyBuilder(
                    SourceAssembly,
                    moduleProps,
                    manifestResources,
                    kind,
                    emitOptions);
            }

            if (debugEntryPoint != null)
            {
                moduleBeingBuilt.SetDebugEntryPoint(debugEntryPoint, diagnostics);
            }

            moduleBeingBuilt.SourceLinkStreamOpt = sourceLinkStream;

            if (embeddedTexts != null)
            {
                moduleBeingBuilt.EmbeddedTexts = embeddedTexts;
            }

            // testData is only passed when running tests.
            if (testData != null)
            {
                //moduleBeingBuilt.SetMethodTestData(testData.Methods);
                //testData.Module = moduleBeingBuilt;
                throw new NotImplementedException();
            }

            return(moduleBeingBuilt);
        }
예제 #6
0
 public DiagnosticAnalyzerService(
     IDiagnosticUpdateSourceRegistrationService registrationService,
     [ImportMany] IEnumerable <Lazy <IAsynchronousOperationListener, FeatureMetadata> > asyncListeners,
     [Import(AllowDefault = true)] IWorkspaceDiagnosticAnalyzerProviderService diagnosticAnalyzerProviderService = null,
     [Import(AllowDefault = true)] AbstractHostDiagnosticUpdateSource hostDiagnosticUpdateSource = null)
     : this(diagnosticAnalyzerProviderService != null ? diagnosticAnalyzerProviderService.GetHostDiagnosticAnalyzerPackages() : SpecializedCollections.EmptyEnumerable <HostDiagnosticAnalyzerPackage>(),
            diagnosticAnalyzerProviderService?.GetAnalyzerAssemblyLoader(),
            hostDiagnosticUpdateSource,
            registrationService, new AggregateAsynchronousOperationListener(asyncListeners, FeatureAttribute.DiagnosticService))
 {
     // diagnosticAnalyzerProviderService and hostDiagnosticUpdateSource can only be null in test hardness otherwise, it should
     // never be null
 }
예제 #7
0
        protected async Task <List <Tuple <Document, IEnumerable <SignatureHelpItem> > > > GetItemsForRelatedDocuments(Document document, IEnumerable <DocumentId> relatedDocuments, int position, SignatureHelpTriggerInfo triggerInfo, CancellationToken cancellationToken)
        {
            var supportedPlatforms = new List <Tuple <Document, IEnumerable <SignatureHelpItem> > >();

            foreach (var relatedDocumentId in relatedDocuments)
            {
                var relatedDocument = document.Project.Solution.GetDocument(relatedDocumentId);
                var semanticModel   = await relatedDocument.GetSemanticModelForSpanAsync(new TextSpan(position, 0), cancellationToken).ConfigureAwait(false);

                var result = await GetItemsWorkerAsync(relatedDocument, position, triggerInfo, cancellationToken).ConfigureAwait(false);

                supportedPlatforms.Add(Tuple.Create(relatedDocument, result != null ? result.Items : SpecializedCollections.EmptyEnumerable <SignatureHelpItem>()));
            }

            return(supportedPlatforms);
        }
예제 #8
0
 public IEnumerable <IEventDefinition> GetEvents(EmitContext context)
 {
     return(SpecializedCollections.EmptyEnumerable <IEventDefinition>());
 }
예제 #9
0
 public IEnumerable <MethodImplementation> GetExplicitImplementationOverrides(EmitContext context)
 {
     return(SpecializedCollections.EmptyEnumerable <MethodImplementation>());
 }
예제 #10
0
 public IEnumerable <IPropertyDefinition> GetProperties(EmitContext context)
 {
     return(SpecializedCollections.EmptyEnumerable <IPropertyDefinition>());
 }
예제 #11
0
 public IEnumerable <ICustomAttribute> GetAttributes(EmitContext context)
 {
     return(SpecializedCollections.EmptyEnumerable <ICustomAttribute>());
 }
예제 #12
0
 public IEnumerable <INestedTypeDefinition> GetNestedTypes(EmitContext context)
 {
     return(SpecializedCollections.EmptyEnumerable <INestedTypeDefinition>());
 }
        private async Task ProcessDocumentAsync(
            Document document,
            ISymbol symbol,
            IReferenceFinder finder,
            ProgressWrapper wrapper)
        {
            using (Logger.LogBlock(FunctionId.FindReference_ProcessDocumentAsync, logDocument, document, symbol, this.cancellationToken))
            {
                try
                {
                    var references = await finder.FindReferencesInDocumentAsync(symbol, document, cancellationToken).ConfigureAwait(false) ?? SpecializedCollections.EmptyEnumerable <ReferenceLocation>();

                    foreach (var location in references)
                    {
                        HandleLocation(symbol, location);
                    }
                }
                finally
                {
                    wrapper.Increment();
                }
            }
        }
예제 #14
0
 internal override IEnumerable <FieldSymbol> GetFieldsToEmit() => SpecializedCollections.EmptyEnumerable <FieldSymbol>();
예제 #15
0
        protected override async Task SearchWorkerAsync(ISymbol symbol, Project project, ICallHierarchySearchCallback callback, IImmutableSet <Document> documents, CancellationToken cancellationToken)
        {
            var overrides = await SymbolFinder.FindOverridesAsync(symbol, project.Solution, cancellationToken : cancellationToken).ConfigureAwait(false);

            foreach (var @override in overrides)
            {
                var sourceLocations = @override.DeclaringSyntaxReferences.Select(d => project.Solution.GetDocument(d.SyntaxTree)).WhereNotNull();
                var bestLocation    = sourceLocations.FirstOrDefault(d => documents == null || documents.Contains(d));
                if (bestLocation != null)
                {
                    var item = await Provider.CreateItem(@override, bestLocation.Project, SpecializedCollections.EmptyEnumerable <Location>(), cancellationToken).ConfigureAwait(false);

                    callback.AddResult(item);
                    cancellationToken.ThrowIfCancellationRequested();
                }
            }
        }
예제 #16
0
 public IEnumerable <IFieldDefinition> GetFields(EmitContext context)
 {
     return(SpecializedCollections.EmptyEnumerable <IFieldDefinition>());
 }
예제 #17
0
 public TreeDumperNode(string text, object value, IEnumerable <TreeDumperNode> children)
 {
     this.Text     = text;
     this.Value    = value;
     this.Children = children ?? SpecializedCollections.EmptyEnumerable <TreeDumperNode>();
 }
예제 #18
0
 public IEnumerable <Cci.TypeReferenceWithAttributes> Interfaces(EmitContext context)
 {
     return(SpecializedCollections.EmptyEnumerable <Cci.TypeReferenceWithAttributes>());
 }
 public static IEnumerable <IPropertySymbol> GetIndexers(this INamespaceOrTypeSymbol?symbol)
 {
     return(symbol == null
         ? SpecializedCollections.EmptyEnumerable <IPropertySymbol>()
         : symbol.GetMembers(WellKnownMemberNames.Indexer).OfType <IPropertySymbol>().Where(p => p.IsIndexer));
 }
 protected override IEnumerable <Task> GetScheduledTasks()
 => SpecializedCollections.EmptyEnumerable <Task>();
예제 #21
0
        private static bool CheckCore(string baseDirectory, IEnumerable <CommandLineAnalyzerReference> analyzerReferences, IAnalyzerAssemblyLoader loader, IEnumerable <string> ignorableReferenceNames)
        {
            var resolvedPaths = new List <string>();

            foreach (var analyzerReference in analyzerReferences)
            {
                string resolvedPath = FileUtilities.ResolveRelativePath(analyzerReference.FilePath, basePath: null, baseDirectory: baseDirectory, searchPaths: SpecializedCollections.EmptyEnumerable <string>(), fileExists: File.Exists);
                if (resolvedPath != null)
                {
                    resolvedPath = FileUtilities.TryNormalizeAbsolutePath(resolvedPath);
                    if (resolvedPath != null)
                    {
                        resolvedPaths.Add(resolvedPath);
                    }
                }

                // Don't worry about paths we can't resolve. The compiler will report an error for that later.
            }

            // First, check that the set of references is complete, modulo items in the safe list.
            foreach (var resolvedPath in resolvedPaths)
            {
                var missingDependencies = AssemblyUtilities.IdentifyMissingDependencies(resolvedPath, resolvedPaths);

                foreach (var missingDependency in missingDependencies)
                {
                    if (!ignorableReferenceNames.Any(name => missingDependency.Name.StartsWith(name)))
                    {
                        CompilerServerLogger.LogError($"Analyzer assembly {resolvedPath} depends on '{missingDependency}' but it was not found.");
                        return(false);
                    }
                }
            }

            // Register analyzers and their dependencies upfront,
            // so that assembly references can be resolved:
            foreach (var resolvedPath in resolvedPaths)
            {
                loader.AddDependencyLocation(resolvedPath);
            }

            // Load all analyzer assemblies:
            var loadedAssemblies = new List <Assembly>();

            foreach (var resolvedPath in resolvedPaths)
            {
                loadedAssemblies.Add(loader.LoadFromPath(resolvedPath));
            }

            // Third, check that the MVIDs of the files on disk match the MVIDs of the loaded assemblies.
            for (int i = 0; i < resolvedPaths.Count; i++)
            {
                var resolvedPath       = resolvedPaths[i];
                var loadedAssembly     = loadedAssemblies[i];
                var resolvedPathMvid   = AssemblyUtilities.ReadMvid(resolvedPath);
                var loadedAssemblyMvid = loadedAssembly.ManifestModule.ModuleVersionId;

                if (resolvedPathMvid != loadedAssemblyMvid)
                {
                    CompilerServerLogger.LogError($"Analyzer assembly {resolvedPath} has MVID '{resolvedPathMvid}' but loaded assembly '{loadedAssembly.FullName}' has MVID '{loadedAssemblyMvid}'.");
                    return(false);
                }
            }

            return(true);
        }
예제 #22
0
 public TreeDumperNode(string text, object?value, IEnumerable <TreeDumperNode>?children)
 {
     Text     = text;
     Value    = value;
     Children = children ?? SpecializedCollections.EmptyEnumerable <TreeDumperNode>();
 }
예제 #23
0
        protected void ReadCompilationOptionsFrom(
            ObjectReader reader,
            out OutputKind outputKind,
            out bool reportSuppressedDiagnostics,
            out string moduleName,
            out string mainTypeName,
            out string scriptClassName,
            out OptimizationLevel optimizationLevel,
            out bool checkOverflow,
            out string cryptoKeyContainer,
            out string cryptoKeyFile,
            out ImmutableArray <byte> cryptoPublicKey,
            out bool?delaySign,
            out Platform platform,
            out ReportDiagnostic generalDiagnosticOption,
            out int warningLevel,
            out IEnumerable <KeyValuePair <string, ReportDiagnostic> > specificDiagnosticOptions,
            out bool concurrentBuild,
            out bool deterministic,
            out bool publicSign,
            out XmlReferenceResolver xmlReferenceResolver,
            out SourceReferenceResolver sourceReferenceResolver,
            out MetadataReferenceResolver metadataReferenceResolver,
            out AssemblyIdentityComparer assemblyIdentityComparer,
            out StrongNameProvider strongNameProvider,
            CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            outputKind = (OutputKind)reader.ReadInt32();
            reportSuppressedDiagnostics = reader.ReadBoolean();
            moduleName   = reader.ReadString();
            mainTypeName = reader.ReadString();

            scriptClassName   = reader.ReadString();
            optimizationLevel = (OptimizationLevel)reader.ReadInt32();
            checkOverflow     = reader.ReadBoolean();

            // REVIEW: is it okay this being not part of snapshot?
            cryptoKeyContainer = reader.ReadString();
            cryptoKeyFile      = reader.ReadString();

            cryptoPublicKey = reader.ReadArray <byte>().ToImmutableArrayOrEmpty();

            delaySign = reader.ReadBoolean() ? (bool?)reader.ReadBoolean() : null;

            platform = (Platform)reader.ReadInt32();
            generalDiagnosticOption = (ReportDiagnostic)reader.ReadInt32();

            warningLevel = reader.ReadInt32();

            // REVIEW: I don't think there is a guarantee on ordering of elements in the immutable dictionary.
            //         unfortunately, we need to sort them to make it deterministic
            //         not sure why CompilationOptions uses SequencialEqual to check options equality
            //         when ordering can change result of it even if contents are same.
            var count = reader.ReadInt32();
            List <KeyValuePair <string, ReportDiagnostic> > specificDiagnosticOptionsList = null;

            if (count > 0)
            {
                specificDiagnosticOptionsList = new List <KeyValuePair <string, ReportDiagnostic> >(count);

                for (var i = 0; i < count; i++)
                {
                    var key   = reader.ReadString();
                    var value = (ReportDiagnostic)reader.ReadInt32();

                    specificDiagnosticOptionsList.Add(KeyValuePair.Create(key, value));
                }
            }

            specificDiagnosticOptions = specificDiagnosticOptionsList ?? SpecializedCollections.EmptyEnumerable <KeyValuePair <string, ReportDiagnostic> >();

            concurrentBuild = reader.ReadBoolean();
            deterministic   = reader.ReadBoolean();
            publicSign      = reader.ReadBoolean();

            // REVIEW: What should I do with these. are these service required when compilation is built ourselves, not through
            //         compiler.
            xmlReferenceResolver      = XmlFileResolver.Default;
            sourceReferenceResolver   = SourceFileResolver.Default;
            metadataReferenceResolver = null;
            assemblyIdentityComparer  = DesktopAssemblyIdentityComparer.Default;
            strongNameProvider        = new DesktopStrongNameProvider();
        }
        private static async Task <Document> InlineTemporaryAsync(Document document, VariableDeclaratorSyntax declarator, CancellationToken cancellationToken)
        {
            var workspace = document.Project.Solution.Workspace;

            // Annotate the variable declarator so that we can get back to it later.
            var updatedDocument = await document.ReplaceNodeAsync(declarator, declarator.WithAdditionalAnnotations(DefinitionAnnotation), cancellationToken).ConfigureAwait(false);

            var semanticModel = await updatedDocument.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            var variableDeclarator = await FindDeclaratorAsync(updatedDocument, cancellationToken).ConfigureAwait(false);

            // Create the expression that we're actually going to inline.
            var expressionToInline = await CreateExpressionToInlineAsync(variableDeclarator, updatedDocument, cancellationToken).ConfigureAwait(false);

            // Collect the identifier names for each reference.
            var local      = (ILocalSymbol)semanticModel.GetDeclaredSymbol(variableDeclarator, cancellationToken);
            var symbolRefs = await SymbolFinder.FindReferencesAsync(local, updatedDocument.Project.Solution, cancellationToken).ConfigureAwait(false);

            var referencedSymbol = symbolRefs.SingleOrDefault(r => Equals(r.Definition, local));
            var references       = referencedSymbol == null?SpecializedCollections.EmptyEnumerable <ReferenceLocation>() : referencedSymbol.Locations;

            var syntaxRoot = await updatedDocument.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            // Collect the topmost parenting expression for each reference.
            var nonConflictingIdentifierNodes = references
                                                .Select(loc => (IdentifierNameSyntax)syntaxRoot.FindToken(loc.Location.SourceSpan.Start).Parent)
                                                .Where(ident => !HasConflict(ident, variableDeclarator));

            // Add referenceAnnotations to identifier nodes being replaced.
            updatedDocument = await updatedDocument.ReplaceNodesAsync(
                nonConflictingIdentifierNodes,
                (o, n) => n.WithAdditionalAnnotations(ReferenceAnnotation),
                cancellationToken).ConfigureAwait(false);

            semanticModel = await updatedDocument.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            variableDeclarator = await FindDeclaratorAsync(updatedDocument, cancellationToken).ConfigureAwait(false);

            // Get the annotated reference nodes.
            nonConflictingIdentifierNodes = await FindReferenceAnnotatedNodesAsync(updatedDocument, cancellationToken).ConfigureAwait(false);

            var topmostParentingExpressions = nonConflictingIdentifierNodes
                                              .Select(ident => GetTopMostParentingExpression(ident))
                                              .Distinct().ToList();

            var originalInitializerSymbolInfo = semanticModel.GetSymbolInfo(variableDeclarator.Initializer.Value, cancellationToken);

            // Checks to see if inlining the temporary variable may change the code's meaning. This can only apply if the variable has two or more
            // references. We later use this heuristic to determine whether or not to display a warning message to the user.
            var mayContainSideEffects = references.Count() > 1 &&
                                        MayContainSideEffects(variableDeclarator.Initializer.Value);

            // Make each topmost parenting statement or Equals Clause Expressions semantically explicit.
            updatedDocument = await updatedDocument.ReplaceNodesAsync(topmostParentingExpressions, (o, n) =>
            {
                var node = Simplifier.Expand(n, semanticModel, workspace, cancellationToken: cancellationToken);

                // warn when inlining into a conditional expression, as the inlined expression will not be executed.
                if (semanticModel.GetSymbolInfo(o, cancellationToken).Symbol is IMethodSymbol {
                    IsConditional : true
                })
                {
                    node = node.WithAdditionalAnnotations(
                        WarningAnnotation.Create(CSharpFeaturesResources.Warning_Inlining_temporary_into_conditional_method_call));
                }

                // If the refactoring may potentially change the code's semantics, display a warning message to the user.
                if (mayContainSideEffects)
                {
                    node = node.WithAdditionalAnnotations(
                        WarningAnnotation.Create(CSharpFeaturesResources.Warning_Inlining_temporary_variable_may_change_code_meaning));
                }

                return(node);
            }, cancellationToken).ConfigureAwait(false);
예제 #25
0
 public IEnumerable <UpdatedEventArgs> GetTodoItemsUpdatedEventArgs(
     Workspace workspace, CancellationToken cancellationToken)
 {
     // Don't need to implement this.  OOP pushes all items over to VS.  So there's no need
     return(SpecializedCollections.EmptyEnumerable <UpdatedEventArgs>());
 }
예제 #26
0
 private static IEnumerable <SyntaxNode> GetParameterListInitializersAndAttributes(BaseParameterListSyntax parameterList) =>
 parameterList != null?
 parameterList.Parameters.SelectMany(p => GetParameterInitializersAndAttributes(p)) :
     SpecializedCollections.EmptyEnumerable <SyntaxNode>();
예제 #27
0
 public OrderableMetadata(string name, IEnumerable <string> after = null, IEnumerable <string> before = null)
 {
     this.AfterTyped  = after ?? SpecializedCollections.EmptyEnumerable <string>();
     this.BeforeTyped = before ?? SpecializedCollections.EmptyEnumerable <string>();
     this.Name        = name;
 }
예제 #28
0
 private static IEnumerable <SyntaxNode> GetTypeParameterListAttributes(TypeParameterListSyntax typeParameterList) =>
 typeParameterList != null?
 typeParameterList.Parameters.SelectMany(p => GetAttributes(p.AttributeLists)) :
     SpecializedCollections.EmptyEnumerable <SyntaxNode>();
예제 #29
0
        private void VerifyRange(string codeWithMarker, string language = LanguageNames.CSharp)
        {
            var codeWithoutMarker = default(string);
            var namedSpans        = (IDictionary <string, IList <TextSpan> >) new Dictionary <string, IList <TextSpan> >();

            MarkupTestFile.GetSpans(codeWithMarker, out codeWithoutMarker, out namedSpans);

            var expectedResult = namedSpans.ContainsKey("r") ? namedSpans["r"] as IEnumerable <TextSpan> : SpecializedCollections.EmptyEnumerable <TextSpan>();

            VerifyRange(codeWithoutMarker, SpecializedCollections.EmptyEnumerable <ICodeCleanupProvider>(), namedSpans["b"], ref expectedResult, language);
        }
예제 #30
0
        private IEnumerable <AbstractFormattingRule> GetTypingRules(Document document, SyntaxToken tokenBeforeCaret)
        {
            // Typing introduces several challenges around formatting.
            // Historically we've shipped several triggers that cause formatting to happen directly while typing.
            // These include formatting of blocks when '}' is typed, formatting of statements when a ';' is typed, formatting of ```case```s when ':' typed, and many other cases.
            // However, formatting during typing can potentially cause problems.  This is because the surrounding code may not be complete,
            // or may otherwise have syntax errors, and thus edits could have unintended consequences.
            //
            // Because of this, we introduce an extra rule into the set of formatting rules whose purpose is to actually make formatting *more*
            // conservative and *less* willing willing to make edits to the tree.
            // The primary effect this rule has is to assume that more code is on a single line (and thus should stay that way)
            // despite what the tree actually looks like.
            //
            // It's ok that this is only during formatting that is caused by an edit because that formatting happens
            // implicitly and thus has to be more careful, whereas an explicit format-document call only happens on-demand
            // and can be more aggressive about what it's doing.
            //
            //
            // For example, say you have the following code.
            //
            // ```c#
            // class C
            // {
            //   int P { get {    return
            // }
            // ```
            //
            // Hitting ';' after 'return' should ideally only affect the 'return statement' and change it to:
            //
            // ```c#
            // class C
            // {
            //   int P { get { return;
            // }
            // ```
            //
            // During a normal format-document call, this is not what would happen.
            // Specifically, because the parser will consume the '}' into the accessor,
            // it will think the accessor spans multiple lines, and thus should not stay on a single line.  This will produce:
            //
            // ```c#
            // class C
            // {
            //   int P
            //   {
            //     get
            //     {
            //       return;
            //     }
            // ```
            //
            // Because it's ok for this to format in that fashion if format-document is invoked,
            // but should not happen during typing, we insert a specialized rule *only* during typing to try to control this.
            // During normal formatting we add 'keep on single line' suppression rules for blocks we find that are on a single line.
            // But that won't work since this span is not on a single line:
            //
            // ```c#
            // class C
            // {
            //   int P { get [|{    return;
            // }|]
            // ```
            //
            // So, during typing, if we see any parent block is incomplete, we'll assume that
            // all our parent blocks are incomplete and we will place the suppression span like so:
            //
            // ```c#
            // class C
            // {
            //   int P { get [|{     return;|]
            // }
            // ```
            //
            // This will have the desired effect of keeping these tokens on the same line, but only during typing scenarios.
            if (tokenBeforeCaret.Kind() == SyntaxKind.CloseBraceToken ||
                tokenBeforeCaret.Kind() == SyntaxKind.EndOfFileToken)
            {
                return(SpecializedCollections.EmptyEnumerable <AbstractFormattingRule>());
            }

            return(SpecializedCollections.SingletonEnumerable(TypingFormattingRule.Instance));
        }