提交 dfb778e3 编写于 作者: C CyrusNajmabadi

Merge branch 'master' into taskAllocations2

@echo off
@if not defined EchoOn @echo off
@setlocal enabledelayedexpansion
set RoslynRoot=%~dp0
......
@echo off
@if not defined EchoOn @echo off
:: Prefer building with Dev15 and try the simple route first (we may be running from a DevCmdPrompt already)
set CommonToolsDir=%VS150COMNTOOLS%
......
......@@ -4411,7 +4411,7 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
generation but may be used by analyzers for producing
errors or warnings.
/embed Embed all source files in the PDB.
/embed:<file list> Embed specfic files the PDB
/embed:<file list> Embed specific files in the PDB
- RESOURCES -
/win32res:<file> Specify a Win32 resource file (.res)
......@@ -4975,4 +4975,4 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<data name="ERR_ThrowMisplaced" xml:space="preserve">
<value>A throw expression is not allowed in this context.</value>
</data>
</root>
\ No newline at end of file
</root>
......@@ -14,15 +14,7 @@ public class CompletionServiceTests
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public void AcquireCompletionService()
{
var hostServices = MefHostServices.Create(
MefHostServices.DefaultAssemblies.Concat(
new[]
{
typeof(CompletionService).Assembly,
typeof(CSharpCompletionService).Assembly
}));
var workspace = new AdhocWorkspace(hostServices);
var workspace = new AdhocWorkspace();
var document = workspace
.AddProject("TestProject", LanguageNames.CSharp)
......
......@@ -249,6 +249,7 @@
<Compile Include="Utilities\SymbolEquivalenceComparerTests.cs" />
<Compile Include="Workspaces\ProjectCacheHostServiceFactoryTests.cs" />
<Compile Include="Workspaces\TextFactoryTests.cs" />
<Compile Include="Workspaces\WorkspaceTests.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
......
// 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.Collections.Generic;
using System.Collections.Immutable;
using System.Threading;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Editor.Implementation.Workspaces;
using Microsoft.CodeAnalysis.Host;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces
{
public class WorkspaceTests
{
[Fact]
public void TestDefaultCompositionIncludesFeaturesLayer()
{
var ws = new AdhocWorkspace();
var csservice = ws.Services.GetLanguageServices(LanguageNames.CSharp).GetService<Microsoft.CodeAnalysis.Completion.CompletionService>();
Assert.NotNull(csservice);
var vbservice = ws.Services.GetLanguageServices(LanguageNames.VisualBasic).GetService<Microsoft.CodeAnalysis.Completion.CompletionService>();
Assert.NotNull(vbservice);
}
}
}
\ No newline at end of file
......@@ -8,12 +8,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Completion
Public Class CompletionServiceTests
<Fact, Trait(Traits.Feature, Traits.Features.Completion)>
Public Sub AcquireCompletionService()
Dim hostServices = MefHostServices.Create(
MefHostServices.DefaultAssemblies.Concat({
GetType(CompletionService).Assembly,
GetType(VisualBasicCompletionService).Assembly}))
Dim workspace = New AdhocWorkspace(hostServices)
Dim workspace = New AdhocWorkspace()
Dim document = workspace _
.AddProject("TestProject", LanguageNames.VisualBasic) _
......
......@@ -43,6 +43,7 @@
<dependency id="System.Threading.Tasks" version="$SystemThreadingTasksVersion$"/>
<dependency id="System.Threading.Tasks.Parallel" version="$SystemThreadingTasksParallelVersion$"/>
<dependency id="System.Threading.Thread" version="$SystemThreadingThreadVersion$" exclude="Compile" />
<dependency id="System.ValueTuple" version="$SystemValueTupleVersion$" />
<dependency id="System.Xml.ReaderWriter" version="$SystemXmlReaderWriterVersion$"/>
<dependency id="System.Xml.XDocument" version="$SystemXmlXDocumentVersion$"/>
<dependency id="System.Xml.XmlDocument" version="$SystemXmlXmlDocumentVersion$" exclude="Compile" />
......
......@@ -70,9 +70,9 @@ Supported Platforms:
<file src="Exes\Toolset\System.Security.Principal.Windows.dll" target="tools" />
<file src="Exes\Toolset\System.Text.Encoding.CodePages.dll" target="tools" />
<file src="Exes\Toolset\System.Threading.Thread.dll" target="tools" />
<file src="Exes\Toolset\System.ValueTuple.dll" target="tools" />
<file src="Exes\Toolset\System.Xml.XmlDocument.dll" target="tools" />
<file src="Exes\Toolset\System.Xml.XPath.dll" target="tools" />
<file src="Exes\Toolset\System.Xml.XPath.XDocument.dll" target="tools" />
<file src="Exes\Toolset\System.ValueTuple.dll" target="tools" />
</files>
</package>
......@@ -283,47 +283,6 @@ private void DoSimultaneousReads(Func<Task<string>> read, string expectedValue)
countdown.Wait();
}
[Fact]
public async Task PersistentService_IdentifierSet()
{
var solution = CreateOrOpenSolution();
var newId = DocumentId.CreateNewId(solution.ProjectIds[0]);
string documentFile = Path.Combine(Path.GetDirectoryName(solution.FilePath), "IdentifierSet.cs");
File.WriteAllText(documentFile, @"
class A
{
public int Test(int i, A a)
{
return a;
}
}");
var newSolution = solution.AddDocument(DocumentInfo.Create(newId, "IdentifierSet", loader: new FileTextLoader(documentFile, Encoding.UTF8), filePath: documentFile));
using (var storage = GetStorage(newSolution))
{
var syntaxTreeStorage = storage as ISyntaxTreeInfoPersistentStorage;
Assert.NotNull(syntaxTreeStorage);
var document = newSolution.GetDocument(newId);
var version = await document.GetSyntaxVersionAsync();
var root = await document.GetSyntaxRootAsync();
Assert.True(syntaxTreeStorage.WriteIdentifierLocations(document, version, root, CancellationToken.None));
Assert.Equal(version, syntaxTreeStorage.GetIdentifierSetVersion(document));
List<int> positions = new List<int>();
Assert.True(syntaxTreeStorage.ReadIdentifierPositions(document, version, "Test", positions, CancellationToken.None));
Assert.Equal(1, positions.Count);
Assert.Equal(29, positions[0]);
}
}
private Solution CreateOrOpenSolution()
{
string solutionFile = Path.Combine(_persistentFolder, "Solution1.sln");
......
Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.Diagnostics.get -> System.Collections.Immutable.ImmutableList<Microsoft.CodeAnalysis.WorkspaceDiagnostic>
\ No newline at end of file
static Microsoft.CodeAnalysis.Host.Mef.DesktopMefHostServices.DefaultAssemblies.get -> System.Collections.Immutable.ImmutableArray<System.Reflection.Assembly>
Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.Diagnostics.get -> System.Collections.Immutable.ImmutableList<Microsoft.CodeAnalysis.WorkspaceDiagnostic>
// 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.Collections.Generic;
using System.Threading;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.FindSymbols;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Versions;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Esent
{
internal partial class EsentPersistentStorage : ISyntaxTreeInfoPersistentStorage
{
private const string IdentifierSetVersion = "<IdentifierSetVersion>";
private const string IdentifierSetSerializationVersion = "1";
private const int NotSupported = -1;
private const int FlushThreshold = 5000;
private int? _identifierSetVersionId;
private bool TryGetUniqueIdentifierId(string identifier, out int id)
{
id = default(int);
if (string.IsNullOrWhiteSpace(identifier))
{
return false;
}
try
{
id = _esentStorage.GetUniqueIdentifierId(identifier);
return true;
}
catch (Exception)
{
return false;
}
}
private bool TryGetIdentifierSetVersionId(out int id)
{
if (_identifierSetVersionId.HasValue)
{
id = _identifierSetVersionId.Value;
return true;
}
if (TryGetUniqueIdentifierId(IdentifierSetVersion, out id))
{
_identifierSetVersionId = id;
return true;
}
return false;
}
private VersionStamp GetIdentifierSetVersion(EsentStorage.Key key)
{
if (!PersistenceEnabled)
{
return VersionStamp.Default;
}
if (!TryGetIdentifierSetVersionId(out var identifierId))
{
return VersionStamp.Default;
}
// TODO: verify that project is in solution associated with the storage
return EsentExceptionWrapper(key, identifierId, GetIdentifierSetVersion, CancellationToken.None);
}
private VersionStamp GetIdentifierSetVersion(EsentStorage.Key key, int identifierId, object unused1, object unused2, CancellationToken cancellationToken)
{
using (var accessor = _esentStorage.GetIdentifierLocationTableAccessor())
using (var stream = accessor.GetReadStream(key, identifierId))
{
if (stream == null)
{
return VersionStamp.Default;
}
using (var reader = new ObjectReader(stream))
{
return VersionStamp.ReadFrom(reader);
}
}
}
public VersionStamp GetIdentifierSetVersion(Document document)
{
if (!PersistenceEnabled)
{
return VersionStamp.Default;
}
if (!TryGetProjectAndDocumentKey(document, out var key))
{
return VersionStamp.Default;
}
return GetIdentifierSetVersion(key);
}
public bool ReadIdentifierPositions(Document document, VersionStamp syntaxVersion, string identifier, List<int> positions, CancellationToken cancellationToken)
{
Contract.ThrowIfTrue(string.IsNullOrWhiteSpace(identifier));
if (!PersistenceEnabled)
{
return false;
}
if (!TryGetProjectAndDocumentKey(document, out var key))
{
return false;
}
var persistedVersion = GetIdentifierSetVersion(key);
if (!document.CanReusePersistedSyntaxTreeVersion(syntaxVersion, persistedVersion))
{
return false;
}
if (!TryGetUniqueIdentifierId(identifier, out var identifierId))
{
return false;
}
return EsentExceptionWrapper(key, identifierId, positions, ReadIdentifierPositions, cancellationToken);
}
private bool ReadIdentifierPositions(EsentStorage.Key key, int identifierId, List<int> positions, object unused, CancellationToken cancellationToken)
{
using (var accessor = _esentStorage.GetIdentifierLocationTableAccessor())
using (var stream = accessor.GetReadStream(key, identifierId))
{
if (stream == null)
{
// no such identifier exist.
return true;
}
using (var reader = new ObjectReader(stream))
{
var formatVersion = reader.ReadString();
if (formatVersion != IdentifierSetSerializationVersion)
{
return false;
}
return ReadFrom(reader, positions, cancellationToken);
}
}
}
private bool DeleteIdentifierLocations(EsentStorage.Key key, CancellationToken cancellationToken)
{
using (var accessor = _esentStorage.GetIdentifierLocationTableAccessor())
{
accessor.Delete(key, cancellationToken);
return accessor.ApplyChanges();
}
}
public bool WriteIdentifierLocations(Document document, VersionStamp version, SyntaxNode root, CancellationToken cancellationToken)
{
Contract.ThrowIfNull(root);
if (!PersistenceEnabled)
{
return false;
}
if (!TryGetProjectAndDocumentKey(document, out var key))
{
return false;
}
return EsentExceptionWrapper(key, document, version, root, WriteIdentifierLocations, cancellationToken);
}
private bool WriteIdentifierLocations(EsentStorage.Key key, Document document, VersionStamp version, SyntaxNode root, CancellationToken cancellationToken)
{
// delete any existing data
if (!DeleteIdentifierLocations(key, cancellationToken))
{
return false;
}
var identifierMap = SharedPools.StringIgnoreCaseDictionary<int>().AllocateAndClear();
Dictionary<string, List<int>> map = null;
try
{
map = CreateIdentifierLocations(document, root, cancellationToken);
// okay, write new data
using (var accessor = _esentStorage.GetIdentifierLocationTableAccessor())
{
// make sure I have all identifier ready before starting big insertion
int identifierId;
foreach (var identifier in map.Keys)
{
if (!TryGetUniqueIdentifierId(identifier, out identifierId))
{
return false;
}
identifierMap[identifier] = identifierId;
}
// save whole map
var uncommittedCount = 0;
foreach (var kv in map)
{
cancellationToken.ThrowIfCancellationRequested();
var identifier = kv.Key;
var positions = kv.Value;
if ((uncommittedCount + positions.Count) > FlushThreshold)
{
accessor.Flush();
uncommittedCount = 0;
}
accessor.PrepareBatchOneInsert();
identifierId = identifierMap[identifier];
using (var stream = accessor.GetWriteStream(key, identifierId))
using (var writer = new ObjectWriter(stream, cancellationToken: cancellationToken))
{
writer.WriteString(IdentifierSetSerializationVersion);
WriteList(writer, positions);
}
accessor.FinishBatchOneInsert();
uncommittedCount += positions.Count;
}
// save special identifier that indicates version for this document
if (!TrySaveIdentifierSetVersion(accessor, key, version))
{
return false;
}
return accessor.ApplyChanges();
}
}
finally
{
SharedPools.StringIgnoreCaseDictionary<int>().ClearAndFree(identifierMap);
Free(map);
}
}
private void Free(Dictionary<string, List<int>> map)
{
if (map == null)
{
return;
}
foreach (var value in map.Values)
{
if (value == null)
{
continue;
}
SharedPools.BigDefault<List<int>>().ClearAndFree(value);
}
SharedPools.StringIgnoreCaseDictionary<List<int>>().ClearAndFree(map);
}
private bool TrySaveIdentifierSetVersion(
EsentStorage.IdentifierLocationTableAccessor accessor, EsentStorage.Key key, VersionStamp version)
{
if (!TryGetIdentifierSetVersionId(out var identifierId))
{
return false;
}
accessor.PrepareBatchOneInsert();
using (var stream = accessor.GetWriteStream(key, identifierId))
using (var writer = new ObjectWriter(stream))
{
version.WriteTo(writer);
}
accessor.FinishBatchOneInsert();
return true;
}
private bool ReadFrom(ObjectReader reader, List<int> result, CancellationToken cancellationToken)
{
var count = reader.ReadInt32();
if (count < 0)
{
return false;
}
for (int i = 0; i < count; i++)
{
cancellationToken.ThrowIfCancellationRequested();
result.Add(reader.ReadInt32());
}
return true;
}
private void WriteList(ObjectWriter writer, List<int> positions)
{
if (positions.Count > FlushThreshold)
{
writer.WriteInt32(NotSupported);
return;
}
writer.WriteInt32(positions.Count);
foreach (var position in positions)
{
writer.WriteInt32(position);
}
}
private static Dictionary<string, List<int>> CreateIdentifierLocations(Document document, SyntaxNode root, CancellationToken cancellationToken)
{
var syntaxFacts = document.GetLanguageService<ISyntaxFactsService>();
var identifierMap = SharedPools.StringIgnoreCaseDictionary<List<int>>().AllocateAndClear();
foreach (var token in root.DescendantTokens(descendIntoTrivia: true))
{
if (token.IsMissing || token.Span.Length == 0)
{
continue;
}
if (syntaxFacts.IsIdentifier(token) || syntaxFacts.IsGlobalNamespaceKeyword(token))
{
var valueText = token.ValueText;
identifierMap.GetOrAdd(valueText, _ => SharedPools.BigDefault<List<int>>().AllocateAndClear()).Add(token.Span.Start);
}
}
return identifierMap;
}
}
}
......@@ -25,7 +25,7 @@ public static MefHostServices DefaultServices
}
private static ImmutableArray<Assembly> s_defaultAssemblies;
private static ImmutableArray<Assembly> DefaultAssemblies
public static ImmutableArray<Assembly> DefaultAssemblies
{
get
{
......
......@@ -79,7 +79,6 @@
<Compile Include="Workspace\CommandLineProject.cs" />
<Compile Include="Workspace\Esent\EsentLogger.cs" />
<Compile Include="Workspace\Esent\EsentPersistentStorage.cs" />
<Compile Include="Workspace\Esent\EsentPersistentStorage_IdentifierTable.cs" />
<Compile Include="Workspace\Esent\EsentStorage.AbstractTable.cs" />
<Compile Include="Workspace\Esent\EsentStorage.AbstractTableAccessor.cs" />
<Compile Include="Workspace\Esent\EsentStorage.cs" />
......@@ -190,4 +189,4 @@
</EmbeddedResource>
</ItemGroup>
<Import Project="..\..\..\..\build\Targets\Imports.targets" />
</Project>
</Project>
\ No newline at end of file
......@@ -96,20 +96,9 @@ public static SymbolInfo GetSymbolInfo(SemanticModel model, SyntaxNode node, Can
ISyntaxFactsService syntaxFacts, Document document, VersionStamp version, SyntaxNode root,
SourceText content, string text, Func<SyntaxToken, bool> candidate, CancellationToken cancellationToken)
{
if (text.Length > 0)
{
using (var positions = SharedPools.BigDefault<List<int>>().GetPooledObject())
{
if (SyntaxTreeIdentifierInfo.TryGetIdentifierLocations(document, version, text, positions.Object, cancellationToken))
{
return GetTokensFromText(root, positions.Object, text, candidate, cancellationToken);
}
}
return GetTokensFromText(syntaxFacts, root, content, text, candidate, cancellationToken);
}
return ImmutableArray<SyntaxToken>.Empty;
return text.Length > 0
? GetTokensFromText(syntaxFacts, root, content, text, candidate, cancellationToken)
: ImmutableArray<SyntaxToken>.Empty;
}
private static ImmutableArray<SyntaxToken> GetTokensFromText(
......
// 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.Collections.Generic;
using System.Threading;
namespace Microsoft.CodeAnalysis.FindSymbols
{
internal interface ISyntaxTreeInfoPersistentStorage
{
VersionStamp GetIdentifierSetVersion(Document document);
bool ReadIdentifierPositions(Document document, VersionStamp version, string identifier, List<int> positions, CancellationToken cancellationToken);
bool WriteIdentifierLocations(Document document, VersionStamp version, SyntaxNode root, CancellationToken cancellationToken);
}
}
......@@ -37,7 +37,7 @@ public static MefHostServices Create(IEnumerable<System.Reflection.Assembly> ass
throw new ArgumentNullException(nameof(assemblies));
}
var compositionConfiguration = new ContainerConfiguration().WithAssemblies(assemblies);
var compositionConfiguration = new ContainerConfiguration().WithAssemblies(assemblies.Distinct());
var container = compositionConfiguration.CreateContainer();
return new MefHostServices(container);
}
......@@ -99,11 +99,15 @@ public static ImmutableArray<Assembly> DefaultAssemblies
private static ImmutableArray<Assembly> LoadDefaultAssemblies()
{
// build a MEF composition using the main workspaces assemblies and the known VisualBasic/CSharp workspace assemblies.
// updated: includes feature assemblies since they now have public API's.
var assemblyNames = new string[]
{
"Microsoft.CodeAnalysis.Workspaces",
"Microsoft.CodeAnalysis.CSharp.Workspaces",
"Microsoft.CodeAnalysis.VisualBasic.Workspaces",
"Microsoft.CodeAnalysis.Features",
"Microsoft.CodeAnalysis.CSharp.Features",
"Microsoft.CodeAnalysis.VisualBasic.Features"
};
return LoadNearbyAssemblies(assemblyNames);
......
......@@ -647,8 +647,6 @@
<Compile Include="FindSymbols\SymbolTree\SymbolTreeInfo.Node.cs" />
<Compile Include="FindSymbols\SymbolTree\SymbolTreeInfo_Serialization.cs" />
<Compile Include="FindSymbols\SyntaxTree\AbstractPersistableState.cs" />
<Compile Include="FindSymbols\SyntaxTree\ISyntaxTreeInfoPersistentStorage.cs" />
<Compile Include="FindSymbols\SyntaxTree\SyntaxTreeIdentifierInfo_Set.cs" />
<Compile Include="Formatting\AbstractSyntaxFormattingService.cs" />
<Compile Include="Formatting\BottomUpBaseIndentationFinder.cs" />
<Compile Include="Formatting\Context\FormattingContext.AnchorData.cs" />
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册