未验证 提交 68ca8272 编写于 作者: B Brett V. Forsgren 提交者: GitHub

Merge pull request #26332 from dotnet/merges/dev15.7.x-to-dev15.7.x-vs-deps

Merge dev15.7.x to dev15.7.x-vs-deps
......@@ -371,6 +371,11 @@ function Pack-One([string]$nuspecFilePath, [string]$packageKind, [string]$packag
$nuspecFileName = Split-Path -leaf $nuspecFilePath
$projectFilePath = Join-Path $nugetDir "NuGetProjectPackUtil.csproj"
$packArgs = "pack -nologo --no-build $projectFilePath $extraArgs /p:NugetPackageKind=$packageKind /p:NuspecFile=$nuspecFilePath /p:NuspecBasePath=$basePath -o $packageOutDir"
if ($official) {
$packArgs = "$packArgs /p:OfficialBuild=true"
}
if ($useConsole) {
Exec-Console $dotnet $packArgs
}
......
......@@ -128,12 +128,12 @@ public static bool IsCompilerAnalyzer(this DiagnosticAnalyzer analyzer)
return false;
}
public static ValueTuple<string, VersionStamp> GetAnalyzerIdAndVersion(this DiagnosticAnalyzer analyzer)
public static (string analyzerId, VersionStamp version) GetAnalyzerIdAndVersion(this DiagnosticAnalyzer analyzer)
{
// Get the unique ID for given diagnostic analyzer.
// note that we also put version stamp so that we can detect changed analyzer.
var typeInfo = analyzer.GetType().GetTypeInfo();
return ValueTuple.Create(analyzer.GetAnalyzerId(), GetAnalyzerVersion(CorLightup.Desktop.GetAssemblyLocation(typeInfo.Assembly)));
return (analyzer.GetAnalyzerId(), GetAnalyzerVersion(CorLightup.Desktop.GetAssemblyLocation(typeInfo.Assembly)));
}
public static string GetAnalyzerAssemblyName(this DiagnosticAnalyzer analyzer)
......
......@@ -3,6 +3,7 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
......@@ -17,20 +18,13 @@ internal partial class DiagnosticIncrementalAnalyzer
/// </summary>
private class StateSet
{
private const string UserDiagnosticsPrefixTableName = "<UserDiagnostics2>";
private readonly string _language;
private readonly DiagnosticAnalyzer _analyzer;
private readonly string _errorSourceName;
// analyzer version this state belong to
private readonly VersionStamp _analyzerVersion;
// name of each analysis kind persistent storage
private readonly string _stateName;
private readonly string _syntaxStateName;
private readonly string _semanticStateName;
private readonly string _nonLocalStateName;
private readonly AnalyzerTypeData _analyzerTypeData;
private readonly ConcurrentDictionary<DocumentId, ActiveFileState> _activeFileStates;
private readonly ConcurrentDictionary<ProjectId, ProjectState> _projectStates;
......@@ -41,23 +35,19 @@ public StateSet(string language, DiagnosticAnalyzer analyzer, string errorSource
_analyzer = analyzer;
_errorSourceName = errorSourceName;
var nameAndVersion = GetNameAndVersion(_analyzer);
_analyzerVersion = nameAndVersion.Item2;
_stateName = nameAndVersion.Item1;
_syntaxStateName = _stateName + ".Syntax";
_semanticStateName = _stateName + ".Semantic";
_nonLocalStateName = _stateName + ".NonLocal";
var (analyzerId, version) = _analyzer.GetAnalyzerIdAndVersion();
_analyzerVersion = version;
_analyzerTypeData = AnalyzerTypeData.ForType(_analyzer.GetType());
Debug.Assert(_analyzerTypeData.StateName == $"{AnalyzerTypeData.UserDiagnosticsPrefixTableName}_{analyzerId}", "Expected persistence information for analyzer instance to be derived from its type alone.");
_activeFileStates = new ConcurrentDictionary<DocumentId, ActiveFileState>(concurrencyLevel: 2, capacity: 10);
_projectStates = new ConcurrentDictionary<ProjectId, ProjectState>(concurrencyLevel: 2, capacity: 1);
}
public string StateName => _stateName;
public string SyntaxStateName => _syntaxStateName;
public string SemanticStateName => _semanticStateName;
public string NonLocalStateName => _nonLocalStateName;
public string StateName => _analyzerTypeData.StateName;
public string SyntaxStateName => _analyzerTypeData.SyntaxStateName;
public string SemanticStateName => _analyzerTypeData.SemanticStateName;
public string NonLocalStateName => _analyzerTypeData.NonLocalStateName;
public string Language => _language;
public string ErrorSourceName => _errorSourceName;
......@@ -265,19 +255,34 @@ public void OnRemoved()
InMemoryStorage.DropCache(Analyzer);
}
/// <summary>
/// Get the unique state name for the given analyzer.
/// Note that this name is used by the underlying persistence stream of the corresponding <see cref="ProjectState"/> to Read/Write diagnostic data into the stream.
/// If any two distinct analyzer have the same diagnostic state name, we will end up sharing the persistence stream between them, leading to duplicate/missing/incorrect diagnostic data.
/// </summary>
private static ValueTuple<string, VersionStamp> GetNameAndVersion(DiagnosticAnalyzer analyzer)
private sealed class AnalyzerTypeData
{
Contract.ThrowIfNull(analyzer);
internal const string UserDiagnosticsPrefixTableName = "<UserDiagnostics2>";
private static readonly ConcurrentDictionary<Type, AnalyzerTypeData> s_analyzerTypeData
= new ConcurrentDictionary<Type, AnalyzerTypeData>();
// Get the unique ID for given diagnostic analyzer.
// note that we also put version stamp so that we can detect changed analyzer.
var tuple = analyzer.GetAnalyzerIdAndVersion();
return ValueTuple.Create(UserDiagnosticsPrefixTableName + "_" + tuple.Item1, tuple.Item2);
private AnalyzerTypeData(Type type)
{
StateName = UserDiagnosticsPrefixTableName + "_" + type.AssemblyQualifiedName;
SyntaxStateName = StateName + ".Syntax";
SemanticStateName = StateName + ".Semantic";
NonLocalStateName = StateName + ".NonLocal";
}
/// <summary>
/// Get the unique state name for the given analyzer.
/// Note that this name is used by the underlying persistence stream of the corresponding <see cref="ProjectState"/> to Read/Write diagnostic data into the stream.
/// If any two distinct analyzer have the same diagnostic state name, we will end up sharing the persistence stream between them, leading to duplicate/missing/incorrect diagnostic data.
/// </summary>
public string StateName { get; }
public string SyntaxStateName { get; }
public string SemanticStateName { get; }
public string NonLocalStateName { get; }
public static AnalyzerTypeData ForType(Type type)
{
return s_analyzerTypeData.GetOrAdd(type, t => new AnalyzerTypeData(t));
}
}
}
}
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.SolutionSize;
using Microsoft.CodeAnalysis.SQLite;
......@@ -17,11 +15,6 @@ namespace Microsoft.CodeAnalysis.UnitTests.WorkspaceServices
/// </remarks>
public class SQLitePersistentStorageTests : AbstractPersistentStorageTests
{
static SQLitePersistentStorageTests()
{
Assert.True(SQLitePersistentStorageService.TryInitializeLibraries());
}
internal override IPersistentStorageService GetStorageService(IPersistentStorageLocationService locationService, ISolutionSizeTracker solutionSizeTracker, IPersistentStorageFaultInjector faultInjector)
=> new SQLitePersistentStorageService(_persistentEnabledOptionService, locationService, solutionSizeTracker, faultInjector);
......
......@@ -52,7 +52,6 @@ internal abstract partial class AbstractProject : ForegroundThreadAffinitizedObj
private readonly Dictionary<string, IVisualStudioHostDocument> _documentMonikers = new Dictionary<string, IVisualStudioHostDocument>(StringComparer.OrdinalIgnoreCase);
private readonly Dictionary<string, VisualStudioAnalyzer> _analyzers = new Dictionary<string, VisualStudioAnalyzer>(StringComparer.OrdinalIgnoreCase);
private readonly Dictionary<DocumentId, IVisualStudioHostDocument> _additionalDocuments = new Dictionary<DocumentId, IVisualStudioHostDocument>();
private readonly Dictionary<DocumentId, List<(IVsHierarchy hierarchy, uint cookie)>> _hierarchyEventSinks = new Dictionary<DocumentId, List<(IVsHierarchy hierarchy, uint cookie)>>();
/// <summary>
/// The list of files which have been added to the project but we aren't tracking since they
......@@ -866,31 +865,16 @@ private static void OnDocumentOpened(object sender, bool isCurrentContext)
if (project.PushingChangesToWorkspace)
{
project.ProjectTracker.NotifyWorkspace(workspace => workspace.OnDocumentOpened(document.Id, document.GetOpenTextBuffer().AsTextContainer(), isCurrentContext));
project.ProjectTracker.NotifyWorkspace(workspace =>
{
workspace.OnDocumentOpened(document.Id, document.GetOpenTextBuffer().AsTextContainer(), isCurrentContext);
(workspace as VisualStudioWorkspaceImpl)?.ConnectToSharedHierarchyEvents(document);
});
}
else
{
StartPushingToWorkspaceAndNotifyOfOpenDocuments(project);
}
var itemId = document.GetItemId();
if (itemId != (uint)VSConstants.VSITEMID.Nil)
{
var sharedHierarchy = LinkedFileUtilities.GetSharedHierarchyForItem(project.Hierarchy, itemId);
if (sharedHierarchy != null)
{
project.ProjectTracker.NotifyWorkspace(workspace =>
{
var eventSink = new HierarchyEventsSink((VisualStudioWorkspaceImpl)workspace, sharedHierarchy, document.Id);
if (ErrorHandler.Succeeded(sharedHierarchy.AdviseHierarchyEvents(eventSink, out var cookie)))
{
project._hierarchyEventSinks.MultiAdd(document.Id, (sharedHierarchy, cookie));
}
});
}
}
}
private static void OnDocumentClosing(object sender, bool updateActiveContext)
......@@ -905,16 +889,6 @@ private static void OnDocumentClosing(object sender, bool updateActiveContext)
{
projectTracker.NotifyWorkspace(workspace => workspace.OnDocumentClosed(document.Id, document.Loader, updateActiveContext));
}
if (project._hierarchyEventSinks.TryGetValue(document.Id, out var subscribedSinks))
{
foreach (var subscribedSink in subscribedSinks)
{
subscribedSink.hierarchy.UnadviseHierarchyEvents(subscribedSink.cookie);
}
project._hierarchyEventSinks.Remove(document.Id);
}
}
private static void OnDocumentUpdatedOnDisk(object sender, EventArgs e)
......@@ -1067,7 +1041,11 @@ internal void AddDocument(IVisualStudioHostDocument document, bool isCurrentCont
if (document.IsOpen)
{
this.ProjectTracker.NotifyWorkspace(workspace => workspace.OnDocumentOpened(document.Id, document.GetOpenTextBuffer().AsTextContainer(), isCurrentContext));
this.ProjectTracker.NotifyWorkspace(workspace =>
{
workspace.OnDocumentOpened(document.Id, document.GetOpenTextBuffer().AsTextContainer(), isCurrentContext);
(workspace as VisualStudioWorkspaceImpl)?.ConnectToSharedHierarchyEvents(document);
});
}
}
......
......@@ -316,10 +316,13 @@ void addToInOrderToPush(AbstractProject project)
if (document.IsOpen)
{
NotifyWorkspace(workspace =>
{
workspace.OnDocumentOpened(
document.Id,
document.GetOpenTextBuffer().AsTextContainer(),
isCurrentContext: LinkedFileUtilities.IsCurrentContextHierarchy(document, _runningDocumentTable)));
isCurrentContext: LinkedFileUtilities.IsCurrentContextHierarchy(document, _runningDocumentTable));
(workspace as VisualStudioWorkspaceImpl)?.ConnectToSharedHierarchyEvents(document);
});
}
}
}
......
......@@ -51,6 +51,8 @@ internal abstract partial class VisualStudioWorkspaceImpl : VisualStudioWorkspac
private readonly Lazy<ForegroundThreadAffinitizedObject> _foregroundObject
= new Lazy<ForegroundThreadAffinitizedObject>(() => new ForegroundThreadAffinitizedObject());
private readonly Dictionary<DocumentId, List<(IVsHierarchy hierarchy, uint cookie)>> _hierarchyEventSinks = new Dictionary<DocumentId, List<(IVsHierarchy hierarchy, uint cookie)>>();
/// <summary>
/// The <see cref="DeferredInitializationState"/> that consists of the <see cref="VisualStudioProjectTracker" />
/// and other UI-initialized types. It will be created as long as a single project has been created.
......@@ -981,6 +983,46 @@ internal void UpdateDocumentContextIfContainsDocument(IVsHierarchy sharedHierarc
OnDocumentContextUpdated(documentId);
}
internal void ConnectToSharedHierarchyEvents(IVisualStudioHostDocument document)
{
Contract.ThrowIfFalse(document.IsOpen);
var project = document.Project;
var itemId = document.GetItemId();
if (itemId != (uint)VSConstants.VSITEMID.Nil)
{
var sharedHierarchy = LinkedFileUtilities.GetSharedHierarchyForItem(project.Hierarchy, itemId);
if (sharedHierarchy != null)
{
ProjectTracker.NotifyWorkspace(workspace =>
{
var eventSink = new HierarchyEventsSink((VisualStudioWorkspaceImpl)workspace, sharedHierarchy, document.Id);
if (ErrorHandler.Succeeded(sharedHierarchy.AdviseHierarchyEvents(eventSink, out var cookie)))
{
_hierarchyEventSinks.MultiAdd(document.Id, (sharedHierarchy, cookie));
}
});
}
}
}
protected override void OnDocumentClosing(DocumentId documentId)
{
base.OnDocumentClosing(documentId);
if (_hierarchyEventSinks.TryGetValue(documentId, out var subscribedSinks))
{
foreach (var subscribedSink in subscribedSinks)
{
subscribedSink.hierarchy.UnadviseHierarchyEvents(subscribedSink.cookie);
}
_hierarchyEventSinks.Remove(documentId);
}
}
/// <summary>
/// Finds the <see cref="DocumentId"/> related to the given <see cref="DocumentId"/> that
/// is in the current context. For regular files (non-shared and non-linked) and closed
......
......@@ -19,7 +19,7 @@ public CSharpWinForms(VisualStudioInstanceFactory instanceFactory)
{
}
[WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/19191"), Trait(Traits.Feature, Traits.Features.WinForms)]
[WpfFact, Trait(Traits.Feature, Traits.Features.WinForms)]
public void AddControl()
{
var project = new ProjectUtils.Project(ProjectName);
......@@ -32,7 +32,7 @@ public void AddControl()
Assert.Contains(@"private System.Windows.Forms.Button SomeButton;", actualText);
}
[WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/19191"), Trait(Traits.Feature, Traits.Features.WinForms)]
[WpfFact, Trait(Traits.Feature, Traits.Features.WinForms)]
public void ChangeControlProperty()
{
var project = new ProjectUtils.Project(ProjectName);
......@@ -45,7 +45,7 @@ public void ChangeControlProperty()
Assert.Contains(@"this.SomeButton.Text = ""NewButtonText""", actualText);
}
[WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/19191"), Trait(Traits.Feature, Traits.Features.WinForms)]
[WpfFact, Trait(Traits.Feature, Traits.Features.WinForms)]
public void ChangeControlPropertyInCode()
{
var project = new ProjectUtils.Project(ProjectName);
......@@ -72,7 +72,7 @@ public void ChangeControlPropertyInCode()
Assert.Equal(expectedPropertyValue, actualPropertyValue);
}
[WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/19191"), Trait(Traits.Feature, Traits.Features.WinForms)]
[WpfFact, Trait(Traits.Feature, Traits.Features.WinForms)]
public void AddClickHandler()
{
var project = new ProjectUtils.Project(ProjectName);
......
......@@ -49,7 +49,7 @@ End Sub
VisualStudio.Editor.Verify.CompletionItemDoNotExist("ToString");
}
[WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/19191"), Trait(Traits.Feature, Traits.Features.WinForms)]
[WpfFact, Trait(Traits.Feature, Traits.Features.WinForms)]
public void AddControl()
{
var project = new ProjectUtils.Project(ProjectName);
......@@ -62,7 +62,7 @@ public void AddControl()
Assert.Contains(@"Friend WithEvents SomeButton As Button", actualText);
}
[WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/19191"), Trait(Traits.Feature, Traits.Features.WinForms)]
[WpfFact, Trait(Traits.Feature, Traits.Features.WinForms)]
public void ChangeControlProperty()
{
var project = new ProjectUtils.Project(ProjectName);
......@@ -75,7 +75,7 @@ public void ChangeControlProperty()
Assert.Contains(@"Me.SomeButton.Text = ""NewButtonText""", actualText);
}
[WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/19191"), Trait(Traits.Feature, Traits.Features.WinForms)]
[WpfFact, Trait(Traits.Feature, Traits.Features.WinForms)]
public void ChangeControlPropertyInCode()
{
var project = new ProjectUtils.Project(ProjectName);
......@@ -102,7 +102,7 @@ public void ChangeControlPropertyInCode()
Assert.Equal(expectedPropertyValue, actualPropertyValue);
}
[WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/19191"), Trait(Traits.Feature, Traits.Features.WinForms)]
[WpfFact, Trait(Traits.Feature, Traits.Features.WinForms)]
public void AddClickHandler()
{
var project = new ProjectUtils.Project(ProjectName);
......
......@@ -10,6 +10,7 @@
using EnvDTE80;
using Microsoft.CodeAnalysis;
using Microsoft.VisualStudio.ProjectSystem.Properties;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.TextManager.Interop;
......@@ -722,14 +723,13 @@ public void OpenFileWithDesigner(string projectName, string relativeFilePath)
public void OpenFile(string projectName, string relativeFilePath)
{
var filePath = GetAbsolutePathForProjectRelativeFilePath(projectName, relativeFilePath);
VsShellUtilities.OpenDocument(ServiceProvider.GlobalProvider, filePath, VSConstants.LOGVIEWID.Code_guid, out _, out _, out _, out var view);
ExecuteCommand(WellKnownCommandNames.File_OpenFile, filePath);
var dte = GetDTE();
while (!dte.ActiveWindow.Caption.Contains(Path.GetFileName(filePath)))
{
Thread.Yield();
}
// Reliably set focus using NavigateToLineAndColumn
var textManager = GetGlobalService<SVsTextManager, IVsTextManager>();
ErrorHandler.ThrowOnFailure(view.GetBuffer(out var textLines));
ErrorHandler.ThrowOnFailure(view.GetCaretPos(out var line, out var column));
ErrorHandler.ThrowOnFailure(textManager.NavigateToLineAndColumn(textLines, VSConstants.LOGVIEWID.Code_guid, line, column, line, column));
}
public void CloseFile(string projectName, string relativeFilePath, bool saveFile)
......
......@@ -23,7 +23,7 @@ internal partial class SQLitePersistentStorageService : AbstractPersistentStorag
[DllImport("kernel32.dll")]
private static extern IntPtr LoadLibrary(string dllToLoad);
internal static bool TryInitializeLibraries() => s_initialized.Value;
private static bool TryInitializeLibraries() => s_initialized.Value;
private static readonly Lazy<bool> s_initialized = new Lazy<bool>(() => TryInitializeLibrariesLazy());
......@@ -88,6 +88,13 @@ protected override string GetDatabaseFilePath(string workingFolderPath)
protected override bool TryOpenDatabase(
Solution solution, string workingFolderPath, string databaseFilePath, out IPersistentStorage storage)
{
if (!TryInitializeLibraries())
{
// SQLite is not supported on the current platform
storage = null;
return false;
}
// try to get db ownership lock. if someone else already has the lock. it will throw
var dbOwnershipLock = TryGetDatabaseOwnership(databaseFilePath);
if (dbOwnershipLock == null)
......
......@@ -28,13 +28,7 @@ public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices)
switch (database)
{
case StorageDatabase.SQLite:
if (!SQLitePersistentStorageService.TryInitializeLibraries())
{
break;
}
var locationService = workspaceServices.GetService<IPersistentStorageLocationService>();
if (locationService != null)
{
return new SQLitePersistentStorageService(optionService, locationService, _solutionSizeTracker);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册