提交 f86e1f20 编写于 作者: H Heejae Chang

Merge branch 'master' of https://github.com/dotnet/roslyn into missingerror

......@@ -95,21 +95,21 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Debugging", "Debugging", "{
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.DiaSymReader.PortablePdb", "src\Debugging\Microsoft.DiaSymReader.PortablePdb\Microsoft.DiaSymReader.PortablePdb.csproj", "{F83343BA-B4EA-451C-B6DB-5D645E6171BC}"
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "TestUtilities.Shared", "src\Test\Utilities\Portable\TestUtilities.Shared.shproj", "{6FF42825-5464-4151-AC55-ED828168C192}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CscCore", "src\Compilers\CSharp\CscCore\CscCore.csproj", "{E3CD2895-76A8-4D11-A316-EA67CB5EA42C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VbcCore", "src\Compilers\VisualBasic\VbcCore\VbcCore.csproj", "{8CE3A581-2969-4864-A803-013E9D977C3A}"
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "TestUtilities.Shared", "src\Test\Utilities\Shared\TestUtilities.Shared.shproj", "{6FF42825-5464-4151-AC55-ED828168C192}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
src\Test\Utilities\Portable\TestUtilities.projitems*{6ff42825-5464-4151-ac55-ed828168c192}*SharedItemsImports = 13
src\Test\Utilities\Shared\TestUtilities.projitems*{6ff42825-5464-4151-ac55-ed828168c192}*SharedItemsImports = 13
src\Compilers\Core\SharedCollections\SharedCollections.projitems*{5f8d2414-064a-4b3a-9b42-8e2a04246be5}*SharedItemsImports = 4
src\Test\Utilities\Shared\TestUtilities.projitems*{f7712928-1175-47b3-8819-ee086753dee2}*SharedItemsImports = 4
src\Compilers\Core\AnalyzerDriver\AnalyzerDriver.projitems*{d0bc9be7-24f6-40ca-8dc6-fcb93bd44b34}*SharedItemsImports = 13
src\Compilers\Core\SharedCollections\SharedCollections.projitems*{afde6bea-5038-4a4a-a88e-dbd2e4088eed}*SharedItemsImports = 4
src\Compilers\Core\AnalyzerDriver\AnalyzerDriver.projitems*{1ee8cad3-55f9-4d91-96b2-084641da9a6c}*SharedItemsImports = 4
src\Compilers\Core\SharedCollections\SharedCollections.projitems*{1ee8cad3-55f9-4d91-96b2-084641da9a6c}*SharedItemsImports = 4
src\Compilers\Core\AnalyzerDriver\AnalyzerDriver.projitems*{1ee8cad3-55f9-4d91-96b2-084641da9a6c}*SharedItemsImports = 4
src\Compilers\CSharp\CSharpAnalyzerDriver\CSharpAnalyzerDriver.projitems*{b501a547-c911-4a05-ac6e-274a50dff30e}*SharedItemsImports = 4
src\Compilers\VisualBasic\BasicAnalyzerDriver\BasicAnalyzerDriver.projitems*{2523d0e6-df32-4a3e-8ae0-a19bffae2ef6}*SharedItemsImports = 4
src\Compilers\Core\SharedCollections\SharedCollections.projitems*{c1930979-c824-496b-a630-70f5369a636f}*SharedItemsImports = 13
......@@ -879,5 +879,6 @@ Global
{F83343BA-B4EA-451C-B6DB-5D645E6171BC} = {5EFE4D73-9608-4E19-83A5-963B02413164}
{E3CD2895-76A8-4D11-A316-EA67CB5EA42C} = {32A48625-F0AD-419D-828B-A50BDABA38EA}
{8CE3A581-2969-4864-A803-013E9D977C3A} = {C65C6143-BED3-46E6-869E-9F0BE6E84C37}
{6FF42825-5464-4151-AC55-ED828168C192} = {A41D1B99-F489-4C43-BBDF-96D61B19A6B9}
EndGlobalSection
EndGlobal
......@@ -79,7 +79,7 @@ restore_nuget()
{
acquire_sem_or_wait "restore_nuget"
local package_name="nuget.12.zip"
local package_name="nuget.14.zip"
local target="/tmp/$package_name"
echo "Installing NuGet Packages $target"
if [ -f $target ]; then
......@@ -112,7 +112,7 @@ run_msbuild()
for i in `seq 1 $RETRY_COUNT`
do
mono $MONO_ARGS ~/.nuget/packages/Microsoft.Build.Mono.Debug/14.1.0-prerelease/lib/MSBuild.exe /v:m /p:SignAssembly=false /p:DebugSymbols=false "$@"
mono $MONO_ARGS ~/.nuget/packages/Microsoft.Build.Mono.Debug/14.1.0-prerelease/lib/MSBuild.exe /v:m /p:SignAssembly=false /p:UseRoslynAnalyzers=false /p:DebugSymbols=false "$@"
if [ $? -eq 0 ]; then
is_good=true
break
......
......@@ -67,8 +67,11 @@
<Compile Include="..\..\Helpers\ConsoleUtil.cs">
<Link>ConsoleUtil.cs</Link>
</Compile>
<Compile Include="..\..\Helpers\NoOpAnalyzerAssemblyLoader.cs">
<Link>ConsoleUtil.cs</Link>
<Compile Include="..\..\Helpers\CoreClrAnalyzerAssemblyLoader.cs">
<Link>CoreClrAnalyzerAssemblyLoader.cs</Link>
</Compile>
<Compile Include="..\..\Helpers\AnalyzerAssemblyLoadUtils.cs">
<Link>AnalyzerAssemblyLoadUtils.cs</Link>
</Compile>
<Compile Include="Csc.cs" />
<Compile Include="Program.cs" />
......
......@@ -3,6 +3,7 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.CodeAnalysis;
namespace Microsoft.CodeAnalysis.CSharp.CommandLine
{
......@@ -12,6 +13,6 @@ public static int Main(string[] args)
=> Csc.Run(args: args,
clientDirectory: AppContext.BaseDirectory,
sdkDirectory: null,
analyzerLoader: new NoOpAnalyzerAssemblyLoader());
analyzerLoader: CoreClrAnalyzerAssemblyLoader.CreateAndSetDefault());
}
}
......@@ -23,9 +23,11 @@
"System.Runtime.Extensions": "4.0.11-beta-23321",
"System.Runtime.Handles": "4.0.1-beta-23321",
"System.Runtime.InteropServices": "4.0.21-beta-23321",
"System.Security.Cryptography.Hashing.Algorithms": "4.0.0-beta-23311",
"System.Runtime.Loader": "4.0.0-beta-23321",
"System.Runtime.Serialization.Json": "4.0.1-beta-23321",
"System.Security.Cryptography.Hashing.Algorithms": "4.0.0-beta-23311",
"System.Text.Encoding": "4.0.11-beta-23321",
"System.Text.Encoding.CodePages": "4.0.1-beta-23321",
"System.Text.Encoding.Extensions": "4.0.11-beta-23321",
"System.Threading": "4.0.11-beta-23321",
"System.Threading.Tasks": "4.0.11-beta-23321",
......
......@@ -478,6 +478,19 @@
"lib/DNXCore50/System.Runtime.InteropServices.dll": {}
}
},
"System.Runtime.Loader/4.0.0-beta-23321": {
"dependencies": {
"System.IO": "[4.0.0, )",
"System.Reflection": "[4.0.0, )",
"System.Runtime": "[4.0.0, )"
},
"compile": {
"ref/dotnet/System.Runtime.Loader.dll": {}
},
"runtime": {
"lib/DNXCore50/System.Runtime.Loader.dll": {}
}
},
"System.Runtime.Serialization.Json/4.0.1-beta-23321": {
"dependencies": {
"System.Private.DataContractSerialization": "[4.0.1-beta-23321, )"
......@@ -569,6 +582,15 @@
"lib/DNXCore50/System.Text.Encoding.dll": {}
}
},
"System.Text.Encoding.CodePages/4.0.1-beta-23321": {
"dependencies": {
"System.Runtime": "[4.0.0, )",
"System.Text.Encoding": "[4.0.10, )"
},
"compile": {
"ref/dotnet/System.Text.Encoding.CodePages.dll": {}
}
},
"System.Text.Encoding.Extensions/4.0.11-beta-23321": {
"dependencies": {
"System.Runtime": "[4.0.0, )",
......@@ -927,6 +949,27 @@
"lib/dotnet/System.Private.Uri.dll": {}
}
},
"runtime.unix.System.Text.Encoding.CodePages/4.0.1-beta-23321": {
"dependencies": {
"System.Collections": "[4.0.10, )",
"System.Globalization": "[4.0.10, )",
"System.IO": "[4.0.10, )",
"System.Reflection": "[4.0.10, )",
"System.Resources.ResourceManager": "[4.0.0, )",
"System.Runtime": "[4.0.20, )",
"System.Runtime.Extensions": "[4.0.10, )",
"System.Runtime.Handles": "[4.0.0, )",
"System.Runtime.InteropServices": "[4.0.20, )",
"System.Text.Encoding": "[4.0.10, )",
"System.Threading": "[4.0.10, )"
},
"compile": {
"ref/dotnet/_._": {}
},
"runtime": {
"lib/dotnet/System.Text.Encoding.CodePages.dll": {}
}
},
"runtime.unix.System.Threading/4.0.11-beta-23321": {
"compile": {
"ref/dotnet/_._": {}
......@@ -1391,6 +1434,19 @@
"lib/DNXCore50/System.Runtime.InteropServices.dll": {}
}
},
"System.Runtime.Loader/4.0.0-beta-23321": {
"dependencies": {
"System.IO": "[4.0.0, )",
"System.Reflection": "[4.0.0, )",
"System.Runtime": "[4.0.0, )"
},
"compile": {
"ref/dotnet/System.Runtime.Loader.dll": {}
},
"runtime": {
"lib/DNXCore50/System.Runtime.Loader.dll": {}
}
},
"System.Runtime.Serialization.Json/4.0.1-beta-23321": {
"dependencies": {
"System.Private.DataContractSerialization": "[4.0.1-beta-23321, )"
......@@ -1482,6 +1538,15 @@
"lib/DNXCore50/System.Text.Encoding.dll": {}
}
},
"System.Text.Encoding.CodePages/4.0.1-beta-23321": {
"dependencies": {
"System.Runtime": "[4.0.0, )",
"System.Text.Encoding": "[4.0.10, )"
},
"compile": {
"ref/dotnet/System.Text.Encoding.CodePages.dll": {}
}
},
"System.Text.Encoding.Extensions/4.0.11-beta-23321": {
"dependencies": {
"System.Runtime": "[4.0.0, )",
......@@ -2002,6 +2067,27 @@
"lib/DNXCore50/System.Runtime.Extensions.dll": {}
}
},
"runtime.win7.System.Text.Encoding.CodePages/4.0.1-beta-23321": {
"dependencies": {
"System.Collections": "[4.0.10, )",
"System.Globalization": "[4.0.10, )",
"System.IO": "[4.0.10, )",
"System.Reflection": "[4.0.10, )",
"System.Resources.ResourceManager": "[4.0.0, )",
"System.Runtime": "[4.0.20, )",
"System.Runtime.Extensions": "[4.0.10, )",
"System.Runtime.Handles": "[4.0.0, )",
"System.Runtime.InteropServices": "[4.0.20, )",
"System.Text.Encoding": "[4.0.10, )",
"System.Threading": "[4.0.10, )"
},
"compile": {
"ref/dotnet/_._": {}
},
"runtime": {
"runtimes/win7/lib/dotnet/System.Text.Encoding.CodePages.dll": {}
}
},
"runtime.win7.System.Threading/4.0.11-beta-23321": {
"compile": {
"ref/dotnet/_._": {}
......@@ -2466,6 +2552,19 @@
"lib/DNXCore50/System.Runtime.InteropServices.dll": {}
}
},
"System.Runtime.Loader/4.0.0-beta-23321": {
"dependencies": {
"System.IO": "[4.0.0, )",
"System.Reflection": "[4.0.0, )",
"System.Runtime": "[4.0.0, )"
},
"compile": {
"ref/dotnet/System.Runtime.Loader.dll": {}
},
"runtime": {
"lib/DNXCore50/System.Runtime.Loader.dll": {}
}
},
"System.Runtime.Serialization.Json/4.0.1-beta-23321": {
"dependencies": {
"System.Private.DataContractSerialization": "[4.0.1-beta-23321, )"
......@@ -2557,6 +2656,15 @@
"lib/DNXCore50/System.Text.Encoding.dll": {}
}
},
"System.Text.Encoding.CodePages/4.0.1-beta-23321": {
"dependencies": {
"System.Runtime": "[4.0.0, )",
"System.Text.Encoding": "[4.0.10, )"
},
"compile": {
"ref/dotnet/System.Text.Encoding.CodePages.dll": {}
}
},
"System.Text.Encoding.Extensions/4.0.11-beta-23321": {
"dependencies": {
"System.Runtime": "[4.0.0, )",
......@@ -2975,6 +3083,18 @@
"runtime.unix.System.Private.Uri.nuspec"
]
},
"runtime.unix.System.Text.Encoding.CodePages/4.0.1-beta-23321": {
"sha512": "ZZS7hqjzl5l0xtJzr/WmK+4Q2Vrr3RcI0KjCNARH2GT2Zcj0Hsnm1Fd+5M9eOg36YbSjy3ZNVn7JbH/Q7ioPEA==",
"type": "Package",
"files": [
"[Content_Types].xml",
"_rels/.rels",
"lib/dotnet/System.Text.Encoding.CodePages.dll",
"package/services/metadata/core-properties/3da52d6f11ac4de8b21b1c4988e87d14.psmdcp",
"ref/dotnet/_._",
"runtime.unix.System.Text.Encoding.CodePages.nuspec"
]
},
"runtime.unix.System.Threading/4.0.11-beta-23321": {
"sha512": "QlIzt08mk+SpmK8PuZJA+H0UfgAurvw5vRcAQImrVxKezS+ILuQ3YTkwQ/Q79koGHfgeFjWMdjYCSGY2KrfVDQ==",
"type": "Package",
......@@ -3385,6 +3505,31 @@
"runtimes/win8-aot/lib/netcore50/zh-hant/System.Runtime.Extensions.xml"
]
},
"runtime.win7.System.Text.Encoding.CodePages/4.0.1-beta-23321": {
"sha512": "0XPZ3FG5C/jV/uzM7YY9ZcdbBMyU3Bh1VmT3v0/EaTQllb9r7+oTy2egWyCdgiFDDKpdfiERVw9EJGQQA3nTDA==",
"type": "Package",
"files": [
"[Content_Types].xml",
"_rels/.rels",
"lib/win8/_._",
"lib/wp8/_._",
"lib/wpa81/_._",
"package/services/metadata/core-properties/b4379f524aba4b37927aad12501a01d3.psmdcp",
"ref/dotnet/_._",
"runtime.win7.System.Text.Encoding.CodePages.nuspec",
"runtimes/win7/lib/dotnet/de/System.Text.Encoding.CodePages.xml",
"runtimes/win7/lib/dotnet/es/System.Text.Encoding.CodePages.xml",
"runtimes/win7/lib/dotnet/fr/System.Text.Encoding.CodePages.xml",
"runtimes/win7/lib/dotnet/it/System.Text.Encoding.CodePages.xml",
"runtimes/win7/lib/dotnet/ja/System.Text.Encoding.CodePages.xml",
"runtimes/win7/lib/dotnet/ko/System.Text.Encoding.CodePages.xml",
"runtimes/win7/lib/dotnet/ru/System.Text.Encoding.CodePages.xml",
"runtimes/win7/lib/dotnet/System.Text.Encoding.CodePages.dll",
"runtimes/win7/lib/dotnet/System.Text.Encoding.CodePages.xml",
"runtimes/win7/lib/dotnet/zh-hans/System.Text.Encoding.CodePages.xml",
"runtimes/win7/lib/dotnet/zh-hant/System.Text.Encoding.CodePages.xml"
]
},
"runtime.win7.System.Threading/4.0.11-beta-23321": {
"sha512": "9S9vqzTsHTp59g7TSJEBUbG7fgZoSM9i1bbP7QWzksILC+ga7Uw8cgg6G/TSgYoCDc8m0gylokUJRFevDyQJbg==",
"type": "Package",
......@@ -4581,6 +4726,18 @@
"System.Runtime.InteropServices.nuspec"
]
},
"System.Runtime.Loader/4.0.0-beta-23321": {
"sha512": "xyfQB/CKuzy/kaiMWtNgX16mMTsgt2ktdmG7COIXBFAkHUARSeBAjMOWkGdNWPzOWINYumqamA8JxGsQlPhuPQ==",
"type": "Package",
"files": [
"[Content_Types].xml",
"_rels/.rels",
"lib/DNXCore50/System.Runtime.Loader.dll",
"package/services/metadata/core-properties/55d60ad8f5d24e06bf703dd426e1ec45.psmdcp",
"ref/dotnet/System.Runtime.Loader.dll",
"System.Runtime.Loader.nuspec"
]
},
"System.Runtime.Serialization.Json/4.0.1-beta-23321": {
"sha512": "TWQRwFnriFMykVgsCyowKFI5eLWoceMtoIrrx9Wd2ZL+XAnsdiYe8OUVeL9Q0kLVs3Ew12sPiXtY2wvVDAYR3w==",
"type": "Package",
......@@ -4758,6 +4915,26 @@
"System.Text.Encoding.nuspec"
]
},
"System.Text.Encoding.CodePages/4.0.1-beta-23321": {
"sha512": "2wTRNrgvdymVYnGfQJFf28UX8N+JipXBZjdLMoecCw5eIVel7ffKYlzQKFbHFmZ8RIxLsjhsr1oEn542acsd/Q==",
"type": "Package",
"files": [
"[Content_Types].xml",
"_rels/.rels",
"lib/MonoAndroid10/_._",
"lib/MonoTouch10/_._",
"lib/xamarinios10/_._",
"lib/xamarinmac20/_._",
"package/services/metadata/core-properties/ea1d25d85d6a4287a5f88d11ba69be14.psmdcp",
"ref/dotnet/System.Text.Encoding.CodePages.dll",
"ref/MonoAndroid10/_._",
"ref/MonoTouch10/_._",
"ref/xamarinios10/_._",
"ref/xamarinmac20/_._",
"runtime.json",
"System.Text.Encoding.CodePages.nuspec"
]
},
"System.Text.Encoding.Extensions/4.0.11-beta-23321": {
"sha512": "DfR8dxgjAyrPeFGLG+O9mLvC5eP76hMMLrOsBMqVBnfwxSa/TYjlNfjluR+bHI/qQZ/W0JELViC93lNX9LGsSQ==",
"type": "Package",
......@@ -5138,9 +5315,11 @@
"System.Runtime.Extensions >= 4.0.11-beta-23321",
"System.Runtime.Handles >= 4.0.1-beta-23321",
"System.Runtime.InteropServices >= 4.0.21-beta-23321",
"System.Runtime.Loader >= 4.0.0-beta-23321",
"System.Runtime.Serialization.Json >= 4.0.1-beta-23321",
"System.Security.Cryptography.Hashing.Algorithms >= 4.0.0-beta-23311",
"System.Text.Encoding >= 4.0.11-beta-23321",
"System.Text.Encoding.CodePages >= 4.0.1-beta-23321",
"System.Text.Encoding.Extensions >= 4.0.11-beta-23321",
"System.Threading >= 4.0.11-beta-23321",
"System.Threading.Tasks >= 4.0.11-beta-23321",
......
......@@ -122,11 +122,11 @@ private Cci.IAssemblyReference TryGetAssemblyScope(NamespaceSymbol @namespace, E
{
var referenceManager = ((CSharpCompilation)moduleBuilder.CommonCompilation).GetBoundReferenceManager();
foreach (var referencedAssembly in referenceManager.ReferencedAssembliesMap.Values)
for (int i = 0; i < referenceManager.ReferencedAssemblies.Length; i++)
{
if ((object)referencedAssembly.Symbol == containingAssembly)
if ((object)referenceManager.ReferencedAssemblies[i] == containingAssembly)
{
if (!referencedAssembly.DeclarationsAccessibleWithoutAlias())
if (!referenceManager.DeclarationsAccessibleWithoutAlias(i))
{
return moduleBuilder.Translate(containingAssembly, diagnostics);
}
......
......@@ -570,15 +570,7 @@ internal bool IsUsingAlias(string name, bool callerIsSemanticModel)
if (seenNamespaceWithExtensionMethods && seenStaticClassWithExtensionMethods)
{
var methodsNoDuplicates = ArrayBuilder<MethodSymbol>.GetInstance();
methodsNoDuplicates.AddRange(methods.Distinct());
if (methodsNoDuplicates.Count < methods.Count)
{
methods.Clear();
methods.AddRange(methodsNoDuplicates);
}
methodsNoDuplicates.Free();
methods.RemoveDuplicates();
}
}
......
......@@ -978,33 +978,47 @@ public override CompilationReference ToMetadataReference(ImmutableArray<string>
return new CSharpCompilationReference(this, aliases, embedInteropTypes);
}
// Get all modules in this compilation, including the source module, added modules, and all
// modules of referenced assemblies that do not come from an assembly with an extern alias.
// Metadata imported from aliased assemblies is not visible at the source level except through
// the use of an extern alias directive. So exclude them from this list which is used to construct
// the global namespace.
private IEnumerable<ModuleSymbol> GetAllUnaliasedModules()
/// <summary>
/// Get all modules in this compilation, including the source module, added modules, and all
/// modules of referenced assemblies that do not come from an assembly with an extern alias.
/// Metadata imported from aliased assemblies is not visible at the source level except through
/// the use of an extern alias directive. So exclude them from this list which is used to construct
/// the global namespace.
/// </summary>
private void GetAllUnaliasedModules(ArrayBuilder<ModuleSymbol> modules)
{
// Get all assemblies in this compilation, including the source assembly and all referenced assemblies.
ArrayBuilder<ModuleSymbol> modules = new ArrayBuilder<ModuleSymbol>();
// NOTE: This includes referenced modules - they count as modules of the compilation assembly.
modules.AddRange(this.Assembly.Modules);
modules.AddRange(Assembly.Modules);
var referenceManager = GetBoundReferenceManager();
foreach (var pair in GetBoundReferenceManager().ReferencedAssembliesMap)
for (int i = 0; i < referenceManager.ReferencedAssemblies.Length; i++)
{
MetadataReference reference = pair.Key;
ReferenceManager.ReferencedAssembly referencedAssembly = pair.Value;
if (reference.Properties.Kind == MetadataImageKind.Assembly) // Already handled modules above.
if (referenceManager.DeclarationsAccessibleWithoutAlias(i))
{
if (referencedAssembly.DeclarationsAccessibleWithoutAlias())
{
modules.AddRange(referencedAssembly.Symbol.Modules);
}
modules.AddRange(referenceManager.ReferencedAssemblies[i].Modules);
}
}
}
return modules;
/// <summary>
/// Return a list of assembly symbols than can be accessed without using an alias.
/// For example:
/// 1) /r:A.dll /r:B.dll -> A, B
/// 2) /r:Foo=A.dll /r:B.dll -> B
/// 3) /r:Foo=A.dll /r:A.dll -> A
/// </summary>
internal void GetUnaliasedReferencedAssemblies(ArrayBuilder<AssemblySymbol> assemblies)
{
var referenceManager = GetBoundReferenceManager();
for (int i = 0; i < referenceManager.ReferencedAssemblies.Length; i++)
{
if (referenceManager.DeclarationsAccessibleWithoutAlias(i))
{
assemblies.Add(referenceManager.ReferencedAssemblies[i]);
}
}
}
/// <summary>
......@@ -1012,7 +1026,7 @@ private IEnumerable<ModuleSymbol> GetAllUnaliasedModules()
/// </summary>
public new MetadataReference GetMetadataReference(IAssemblySymbol assemblySymbol)
{
return this.GetBoundReferenceManager().ReferencedAssembliesMap.Where(kvp => object.ReferenceEquals(kvp.Value.Symbol, assemblySymbol)).Select(kvp => kvp.Key).FirstOrDefault();
return base.GetMetadataReference(assemblySymbol);
}
#endregion
......@@ -1066,15 +1080,19 @@ internal new NamespaceSymbol GlobalNamespace
if ((object)_lazyGlobalNamespace == null)
{
// Get the root namespace from each module, and merge them all together
HashSet<NamespaceSymbol> allGlobalNamespaces = new HashSet<NamespaceSymbol>();
foreach (ModuleSymbol module in GetAllUnaliasedModules())
{
allGlobalNamespaces.Add(module.GlobalNamespace);
}
// Get all modules in this compilation, ones referenced directly by the compilation
// as well as those referenced by all referenced assemblies.
var result = MergedNamespaceSymbol.Create(new NamespaceExtent(this),
var modules = ArrayBuilder<ModuleSymbol>.GetInstance();
GetAllUnaliasedModules(modules);
var result = MergedNamespaceSymbol.Create(
new NamespaceExtent(this),
null,
allGlobalNamespaces.AsImmutable());
modules.SelectDistinct(m => m.GlobalNamespace));
modules.Free();
Interlocked.CompareExchange(ref _lazyGlobalNamespace, result, null);
}
......@@ -1126,12 +1144,13 @@ internal bool GetExternAliasTarget(string aliasName, out NamespaceSymbol @namesp
}
ArrayBuilder<NamespaceSymbol> builder = null;
foreach (var referencedAssembly in GetBoundReferenceManager().ReferencedAssembliesMap.Values)
var referenceManager = GetBoundReferenceManager();
for (int i = 0; i < referenceManager.ReferencedAssemblies.Length; i++)
{
if (referencedAssembly.Aliases.Contains(aliasName))
if (referenceManager.AliasesOfReferencedAssemblies[i].Contains(aliasName))
{
builder = builder ?? ArrayBuilder<NamespaceSymbol>.GetInstance();
builder.Add(referencedAssembly.Symbol.GlobalNamespace);
builder.Add(referenceManager.ReferencedAssemblies[i].GlobalNamespace);
}
}
......@@ -2791,19 +2810,6 @@ protected override INamedTypeSymbol CommonObjectType
get { return this.ObjectType; }
}
protected override MetadataReference CommonGetMetadataReference(IAssemblySymbol assemblySymbol)
{
var symbol = assemblySymbol as AssemblySymbol;
if ((object)symbol != null)
{
return this.GetMetadataReference(symbol);
}
else
{
return null;
}
}
protected override IMethodSymbol CommonGetEntryPoint(CancellationToken cancellationToken)
{
return this.GetEntryPoint(cancellationToken);
......
......@@ -732,12 +732,15 @@ private NamedTypeSymbol ApplyGenericArguments(NamedTypeSymbol symbol, Type[] typ
Debug.Assert(this is SourceAssemblySymbol,
"Never include references for a non-source assembly, because they don't know about aliases.");
var assemblies = ArrayBuilder<AssemblySymbol>.GetInstance();
DeclaringCompilation.GetUnaliasedReferencedAssemblies(assemblies);
// Lookup in references
foreach (var reference in GetUnaliasedReferencedAssemblies())
foreach (var assembly in assemblies)
{
Debug.Assert(!(this is SourceAssemblySymbol && reference.IsMissing)); // Non-source assemblies can have missing references
Debug.Assert(!(this is SourceAssemblySymbol && assembly.IsMissing)); // Non-source assemblies can have missing references
NamedTypeSymbol candidate = GetTopLevelTypeByMetadataName(reference, ref metadataName, assemblyOpt);
NamedTypeSymbol candidate = GetTopLevelTypeByMetadataName(assembly, ref metadataName, assemblyOpt);
if (isWellKnownType && !IsValidWellKnownType(candidate))
{
......@@ -756,19 +759,21 @@ private NamedTypeSymbol ApplyGenericArguments(NamedTypeSymbol symbol, Type[] typ
// duplicate
if (warnings == null)
{
return null;
result = null;
}
else
{
// The predefined type '{0}' is defined in multiple assemblies in the global alias; using definition from '{1}'
warnings.Add(ErrorCode.WRN_MultiplePredefTypes, NoLocation.Singleton, result, result.ContainingAssembly);
return result;
}
break;
}
result = candidate;
}
assemblies.Free();
return result;
}
......@@ -785,46 +790,6 @@ private bool IsValidWellKnownType(NamedTypeSymbol result)
return result.DeclaredAccessibility == Accessibility.Public || IsSymbolAccessible(result, this);
}
/// <summary>
/// Return a list of assembly symbols than can be accessed without using an alias.
/// For example:
/// 1) /r:A.dll /r:B.dll -> A, B
/// 2) /r:Foo=A.dll /r:B.dll -> B
/// 3) /r:Foo=A.dll /r:A.dll -> A
///
/// Note that it only makes sense to call this method on a SourceAssemblySymbol since
/// alias information is per-compilation.
/// </summary>
private ImmutableArray<AssemblySymbol> GetUnaliasedReferencedAssemblies()
{
CSharpCompilation compilation = this.DeclaringCompilation;
Debug.Assert(compilation != null, "There's an answer, but we don't expect this to happen");
// if (compilation == null) return this.Modules[0].GetReferencedAssemblySymbols();
ArrayBuilder<AssemblySymbol> references = null;
foreach (var pair in compilation.GetBoundReferenceManager().ReferencedAssembliesMap)
{
MetadataReference reference = pair.Key;
CSharpCompilation.ReferenceManager.ReferencedAssembly referencedAssembly = pair.Value;
if (reference.Properties.Kind == MetadataImageKind.Assembly)
{
if (referencedAssembly.DeclarationsAccessibleWithoutAlias())
{
if (references == null)
{
references = ArrayBuilder<AssemblySymbol>.GetInstance();
}
references.Add(referencedAssembly.Symbol);
}
}
}
return references == null
? ImmutableArray<AssemblySymbol>.Empty
: references.ToImmutableAndFree();
}
private static NamedTypeSymbol GetTopLevelTypeByMetadataName(AssemblySymbol assembly, ref MetadataTypeName metadataName, AssemblyIdentity assemblyOpt)
{
var result = assembly.LookupTopLevelMetadataType(ref metadataName, digThroughForwardedTypes: false);
......
......@@ -39,14 +39,11 @@ internal sealed override bool IsMissing
/// Returns an array of assembly identities for assemblies referenced by this module.
/// Items at the same position from GetReferencedAssemblies and from GetReferencedAssemblySymbols
/// should correspond to each other.
///
/// The array and its content is provided by ReferenceManager and must not be modified.
/// </summary>
/// <returns></returns>
internal sealed override ImmutableArray<AssemblyIdentity> GetReferencedAssemblies()
{
AssertReferencesInitialized();
return _moduleReferences.Names;
return _moduleReferences.Identities;
}
/// <summary>
......@@ -55,8 +52,6 @@ internal sealed override ImmutableArray<AssemblyIdentity> GetReferencedAssemblie
/// from GetReferencedAssemblySymbols should correspond to each other. If reference is
/// not resolved by compiler, GetReferencedAssemblySymbols returns MissingAssemblySymbol in the
/// corresponding item.
///
/// The array and its content is provided by ReferenceManager and must not be modified.
/// </summary>
internal sealed override ImmutableArray<AssemblySymbol> GetReferencedAssemblySymbols()
{
......
......@@ -185,7 +185,7 @@ internal override void SetReferences(ModuleReferences<AssemblySymbol> moduleRefe
ImmutableArray<AssemblySymbol> underlyingBoundReferences = _underlyingModule.GetReferencedAssemblySymbols();
ImmutableArray<AssemblySymbol> referencedAssemblySymbols = moduleReferences.Symbols;
Debug.Assert(referencedAssemblySymbols.Length == moduleReferences.Names.Length);
Debug.Assert(referencedAssemblySymbols.Length == moduleReferences.Identities.Length);
Debug.Assert(referencedAssemblySymbols.Length <= underlyingBoundReferences.Length); // Linked references are filtered out.
int i, j;
......@@ -203,8 +203,8 @@ internal override void SetReferences(ModuleReferences<AssemblySymbol> moduleRefe
new AssemblyIdentity(name: originatingSourceAssemblyDebugOnly.Name) :
referencedAssemblySymbols[i].Identity;
Debug.Assert(identityComparer.Compare(moduleReferences.Names[i], definitionIdentity) != AssemblyIdentityComparer.ComparisonResult.NotEquivalent);
Debug.Assert(identityComparer.Compare(moduleReferences.Names[i], underlyingBoundReferences[j].Identity) != AssemblyIdentityComparer.ComparisonResult.NotEquivalent);
Debug.Assert(identityComparer.Compare(moduleReferences.Identities[i], definitionIdentity) != AssemblyIdentityComparer.ComparisonResult.NotEquivalent);
Debug.Assert(identityComparer.Compare(moduleReferences.Identities[i], underlyingBoundReferences[j].Identity) != AssemblyIdentityComparer.ComparisonResult.NotEquivalent);
#endif
if (!ReferenceEquals(referencedAssemblySymbols[i], underlyingBoundReferences[j]))
......
......@@ -60,7 +60,6 @@
<DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
<OutputPath>bin\Release\</OutputPath>
......@@ -69,7 +68,6 @@
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.CSharp" />
......
......@@ -184,7 +184,6 @@
<ItemGroup>
<Reference Include="Microsoft.CSharp" />
<Reference Include="System" />
<Reference Include="System.configuration" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
......@@ -199,4 +198,4 @@
<Import Project="..\..\..\..\..\build\Targets\VSL.Imports.targets" />
<Import Project="..\..\..\..\..\build\Targets\Roslyn.Toolsets.Xunit.targets" />
</ImportGroup>
</Project>
</Project>
\ No newline at end of file
......@@ -53,6 +53,9 @@
<Compile Include="..\..\Helpers\AbstractAnalyzerAssemblyLoader.cs">
<Link>AbstractAnalyzerAssemblyLoader.cs</Link>
</Compile>
<Compile Include="..\..\Helpers\AnalyzerAssemblyLoadUtils.cs">
<Link>AnalyzerAssemblyLoadUtils.cs</Link>
</Compile>
<Compile Include="..\..\Helpers\ConsoleUtil.cs">
<Link>ConsoleUtil.cs</Link>
</Compile>
......@@ -77,4 +80,4 @@
<ImportGroup Label="Targets">
<Import Project="..\..\..\..\build\Targets\VSL.Imports.targets" />
</ImportGroup>
</Project>
\ No newline at end of file
</Project>
......@@ -24,6 +24,7 @@
<Compile Include="AnalyzerFileReferenceTests.cs" />
<Compile Include="AssemblyUtilitiesTests.cs" />
<Compile Include="AsyncQueueTests.cs" />
<Compile Include="Collections\ArrayBuilderTests.cs" />
<Compile Include="Collections\BoxesTest.cs" />
<Compile Include="Collections\ByteSequenceComparerTests.cs" />
<Compile Include="Diagnostics\DiagnosticLocalizationTests.cs" />
......
// 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 Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.UnitTests.Collections
{
internal class ArrayBuilderTests
{
[Fact]
public void RemoveDuplicates1()
{
var builder = new ArrayBuilder<int> { 1, 2, 3, 2, 4, 5, 1 };
builder.RemoveDuplicates();
AssertEx.Equal(new[] { 1, 2, 3, 4, 5 }, builder);
builder = new ArrayBuilder<int> { 1 };
builder.RemoveDuplicates();
AssertEx.Equal(new[] { 1 }, builder);
builder = new ArrayBuilder<int>();
builder.RemoveDuplicates();
AssertEx.Equal(new int[0], builder);
}
[Fact]
public void SelectDistinct1()
{
var builder = new ArrayBuilder<int> { 1, 2, 3, 2, 4, 5, 1 };
AssertEx.Equal(new[] { 1, 2, 3, 4, 5 }, builder.SelectDistinct(n => n));
builder = new ArrayBuilder<int> { 1 };
AssertEx.Equal(new[] { 1 }, builder.SelectDistinct(n => n));
builder = new ArrayBuilder<int>();
AssertEx.Equal(new int[0], builder.SelectDistinct(n => n));
builder = new ArrayBuilder<int> { 1, 2, 3, 2, 4, 5, 1 };
AssertEx.Equal(new[] { 10 }, builder.SelectDistinct(n => 10));
builder = new ArrayBuilder<int> { 1, 2, 3, 2, 4, 5, 1 };
AssertEx.Equal(new byte[] { 1, 2, 3, 4, 5 }, builder.SelectDistinct(n => (byte)n));
}
}
}
......@@ -737,11 +737,9 @@ public ISymbol GetAssemblyOrModuleSymbol(MetadataReference reference)
/// <param name="assemblySymbol">The target symbol.</param>
public MetadataReference GetMetadataReference(IAssemblySymbol assemblySymbol)
{
return CommonGetMetadataReference(assemblySymbol);
return GetBoundReferenceManager().GetMetadataReference(assemblySymbol);
}
protected abstract MetadataReference CommonGetMetadataReference(IAssemblySymbol assemblySymbol);
/// <summary>
/// Assembly identities of all assemblies directly referenced by this compilation.
/// </summary>
......
......@@ -6,9 +6,7 @@
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Reflection.PortableExecutable;
using System.Threading;
using Microsoft.Cci;
using Microsoft.CodeAnalysis.CodeGen;
using Microsoft.CodeAnalysis.Emit.NoPia;
using Roslyn.Utilities;
......@@ -237,7 +235,7 @@ internal sealed override Cci.ITypeReference Translate(ITypeSymbol symbol, Syntax
return Translate((TTypeSymbol)symbol, (TSyntaxNode)syntaxNodeOpt, diagnostics);
}
internal sealed override IMethodReference Translate(IMethodSymbol symbol, DiagnosticBag diagnostics, bool needDeclaration)
internal sealed override Cci.IMethodReference Translate(IMethodSymbol symbol, DiagnosticBag diagnostics, bool needDeclaration)
{
return Translate((TMethodSymbol)symbol, diagnostics, needDeclaration);
}
......@@ -294,28 +292,21 @@ private static void VisitTopLevelType(Cci.NoPiaReferenceIndexer noPiaIndexer, Cc
private ImmutableArray<Cci.AssemblyReferenceAlias> CalculateAssemblyReferenceAliases(EmitContext context)
{
var result = ArrayBuilder<Cci.AssemblyReferenceAlias>.GetInstance(_compilation.ExternalReferences.Length);
var result = ArrayBuilder<Cci.AssemblyReferenceAlias>.GetInstance();
var referenceManager = _compilation.GetBoundReferenceManager();
// Enumerate external references (#r's don't define aliases) to preserve the order.
foreach (MetadataReference reference in _compilation.ExternalReferences)
foreach (var assemblyAndAliases in _compilation.GetBoundReferenceManager().GetReferencedAssemblyAliases())
{
// duplicate references might have been skipped by the assembly binder:
var assembly = assemblyAndAliases.Item1;
var aliases = assemblyAndAliases.Item2;
IAssemblySymbol symbol;
ImmutableArray<string> aliases;
if (referenceManager.TryGetReferencedAssemblySymbol(reference, out symbol, out aliases))
for (int i = 0; i < aliases.Length; i++)
{
for (int i = 0; i < aliases.Length; i++)
{
string alias = aliases[i];
string alias = aliases[i];
// filter out duplicates and global aliases:
if (alias != MetadataReferenceProperties.GlobalAlias && aliases.IndexOf(alias, 0, i) < 0)
{
result.Add(new Cci.AssemblyReferenceAlias(alias, Translate(symbol, context.Diagnostics)));
}
// filter out duplicates and global aliases:
if (alias != MetadataReferenceProperties.GlobalAlias && aliases.IndexOf(alias, 0, i) < 0)
{
result.Add(new Cci.AssemblyReferenceAlias(alias, Translate(assembly, context.Diagnostics)));
}
}
}
......
// 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.Diagnostics;
using System.Linq;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis
{
internal partial class CommonReferenceManager<TCompilation, TAssemblySymbol>
......
// 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.Diagnostics;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis
{
......
......@@ -4,8 +4,6 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis
......@@ -25,9 +23,8 @@ internal partial class CommonReferenceManager<TCompilation, TAssemblySymbol>
/// </summary>
///
/// <param name="assemblies">
/// The set of AssemblyData objects describing assemblies, for which this method should
/// resolve references and find suitable AssemblySymbols. This array is not modified by the
/// method.
/// The set of <see cref="AssemblyData"/> objects describing assemblies, for which this method should
/// resolve references and find suitable AssemblySymbols.
/// </param>
/// <param name="hasCircularReference">
/// True if the assembly being compiled is indirectly referenced through some of its own references.
......@@ -36,18 +33,18 @@ internal partial class CommonReferenceManager<TCompilation, TAssemblySymbol>
/// The definition index of the COR library.
/// </param>
/// <returns>
/// An array of Binding structures describing the result. It has the same amount of items as
/// the input assemblies array, Binding structure for each input AssemblyData object resides
/// An array of <see cref="BoundInputAssembly"/> structures describing the result. It has the same amount of items as
/// the input assemblies array, <see cref="BoundInputAssembly"/> for each input AssemblyData object resides
/// at the same position.
///
/// Each Binding structure contains the following data:
/// Each <see cref="BoundInputAssembly"/> contains the following data:
///
/// - Suitable AssemblySymbol instance for the corresponding assembly,
/// null reference if none is available/found. Always null for the first element, which corresponds to the assembly being built.
///
/// - Result of resolving assembly references of the corresponding assembly
/// against provided set of assembly definitions. Essentially, this is an array returned by
/// AssemblyData.BindAssemblyReferences method.
/// <see cref="AssemblyData.BindAssemblyReferences(ImmutableArray{AssemblyData}, AssemblyIdentityComparer)"/> method.
/// </returns>
internal BoundInputAssembly[] Bind(
ImmutableArray<AssemblyData> assemblies,
......
......@@ -5,12 +5,12 @@
using System.Collections.Immutable;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis
{
using System.Reflection;
using MetadataOrDiagnostic = System.Object;
/// <summary>
......@@ -54,8 +54,6 @@ protected struct ResolvedReference
private readonly int _index;
private readonly ImmutableArray<string> _aliases;
public static readonly ResolvedReference Skipped = default(ResolvedReference);
public ResolvedReference(int index, MetadataImageKind kind, ImmutableArray<string> aliases)
{
Debug.Assert(index >= 0);
......@@ -74,6 +72,9 @@ public ImmutableArray<string> Aliases
}
}
/// <summary>
/// default(<see cref="ResolvedReference"/>) is considered skipped.
/// </summary>
public bool IsSkipped
{
get
......@@ -91,6 +92,9 @@ public MetadataImageKind Kind
}
}
/// <summary>
/// Index into an array of assemblies or an array of modules, depending on <see cref="Kind"/>.
/// </summary>
public int Index
{
get
......@@ -324,6 +328,13 @@ public ReferencedAssemblyIdentity(AssemblyIdentity identity, MetadataReference m
boundReferenceDirectives = ImmutableArray<MetadataReference>.Empty;
}
// We enumerated references in reverse order in the above code
// and thus assemblies and modules in the builders are reversed.
// Fix up all the indices and reverse the builder content now to get
// the ordering matching the references.
//
// Also fills in aliases.
for (int i = 0; i < referenceMap.Length; i++)
{
if (!referenceMap[i].IsSkipped)
......@@ -331,6 +342,7 @@ public ReferencedAssemblyIdentity(AssemblyIdentity identity, MetadataReference m
int count = referenceMap[i].Kind == MetadataImageKind.Assembly
? ((object)assembliesBuilder == null ? 0 : assembliesBuilder.Count)
: ((object)modulesBuilder == null ? 0 : modulesBuilder.Count);
int reversedIndex = count - 1 - referenceMap[i].Index;
referenceMap[i] = new ResolvedReference(reversedIndex, referenceMap[i].Kind, GetAliases(references[i], aliasMap));
}
......@@ -345,7 +357,7 @@ public ReferencedAssemblyIdentity(AssemblyIdentity identity, MetadataReference m
assembliesBuilder.ReverseContents();
assemblies = assembliesBuilder.ToImmutableAndFree();
}
if (modulesBuilder == null)
{
modules = ImmutableArray<PEModule>.Empty;
......@@ -542,6 +554,7 @@ private static void AddAssembly(AssemblyData data, int referenceIndex, ResolvedR
assemblies = ArrayBuilder<AssemblyData>.GetInstance();
}
// aliases will be filled in later:
referenceMap[referenceIndex] = new ResolvedReference(assemblies.Count, MetadataImageKind.Assembly, default(ImmutableArray<string>));
assemblies.Add(data);
}
......
......@@ -4,12 +4,8 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis
......@@ -36,33 +32,17 @@ internal abstract class CommonReferenceManager
/// Enumerates all referenced assemblies.
/// </summary>
internal abstract IEnumerable<KeyValuePair<MetadataReference, IAssemblySymbol>> GetReferencedAssemblies();
/// <summary>
/// Enumerates all referenced assemblies and their aliases.
/// </summary>
internal abstract IEnumerable<ValueTuple<IAssemblySymbol, ImmutableArray<string>>> GetReferencedAssemblyAliases();
internal abstract bool TryGetReferencedAssemblySymbol(MetadataReference reference, out IAssemblySymbol symbol, out ImmutableArray<string> aliases);
internal abstract MetadataReference GetMetadataReference(IAssemblySymbol assemblySymbol);
}
internal partial class CommonReferenceManager<TCompilation, TAssemblySymbol> : CommonReferenceManager
{
internal struct ReferencedAssembly
{
public readonly TAssemblySymbol Symbol;
// All aliases given to this symbol via metadata references, may contain duplicates
public readonly ImmutableArray<string> Aliases;
public ReferencedAssembly(TAssemblySymbol symbol, ImmutableArray<string> aliases)
{
Debug.Assert(symbol != null && !aliases.IsDefault);
this.Symbol = symbol;
this.Aliases = aliases;
}
public bool DeclarationsAccessibleWithoutAlias()
{
return Aliases.Length == 0 || Aliases.IndexOf(MetadataReferenceProperties.GlobalAlias) >= 0;
}
}
/// <summary>
/// If the compilation being built represents an assembly its assembly name.
/// If the compilation being built represents a module, the name of the
......@@ -98,10 +78,10 @@ public bool DeclarationsAccessibleWithoutAlias()
private ThreeState _lazyHasCircularReference;
/// <summary>
/// A map from a metadata reference to an AssemblySymbol used for it. Do not access
/// directly, use <see cref="ReferencedAssembliesMap"/> property instead.
/// A map from a metadata reference to an index to <see cref="_lazyReferencedAssemblies"/> array. Do not access
/// directly, use <see cref="_lazyReferencedAssembliesMap"/> property instead.
/// </summary>
private Dictionary<MetadataReference, ReferencedAssembly> _lazyReferencedAssembliesMap;
private Dictionary<MetadataReference, int> _lazyReferencedAssembliesMap;
/// <summary>
/// A map from a net-module metadata reference to the index of the corresponding module
......@@ -109,7 +89,7 @@ public bool DeclarationsAccessibleWithoutAlias()
/// </summary>
/// <remarks>
/// Subtract one from the index (for the manifest module) to find the corresponding elements
/// of lazyReferencedModules and lazyReferencedModulesReferences.
/// of <see cref="_lazyReferencedModules"/> and <see cref="_lazyReferencedModulesReferences"/>.
/// </remarks>
private Dictionary<MetadataReference, int> _lazyReferencedModuleIndexMap;
......@@ -126,7 +106,7 @@ public bool DeclarationsAccessibleWithoutAlias()
/// The references are in the order they appear in syntax trees. This order is currently preserved
/// as syntax trees are added or removed, but we might decide to share reference manager between compilations
/// with different order of #r's. It doesn't seem this would be an issue since all #r's within the compilation
/// has the same "priority" with respect to each other.
/// have the same "priority" with respect to each other.
/// </remarks>
private ImmutableArray<MetadataReference> _lazyDirectiveReferences;
......@@ -154,7 +134,7 @@ public bool DeclarationsAccessibleWithoutAlias()
/// Standalone modules referenced by the compilation (doesn't include the manifest module of the compilation).
/// </summary>
/// <remarks>
/// lazyReferencedModules[i] corresponds to lazyReferencedModulesReferences[i].
/// <see cref="_lazyReferencedModules"/>[i] corresponds to <see cref="_lazyReferencedModulesReferences"/>[i].
/// </remarks>
private ImmutableArray<PEModule> _lazyReferencedModules;
......@@ -162,7 +142,7 @@ public bool DeclarationsAccessibleWithoutAlias()
/// References of standalone modules referenced by the compilation (doesn't include the manifest module of the compilation).
/// </summary>
/// <remarks>
/// lazyReferencedModules[i] corresponds to lazyReferencedModulesReferences[i].
/// <see cref="_lazyReferencedModules"/>[i] corresponds to <see cref="_lazyReferencedModulesReferences"/>[i].
/// </remarks>
private ImmutableArray<ModuleReferences<TAssemblySymbol>> _lazyReferencedModulesReferences;
......@@ -171,6 +151,14 @@ public bool DeclarationsAccessibleWithoutAlias()
/// </summary>
private ImmutableArray<TAssemblySymbol> _lazyReferencedAssemblies;
/// <summary>
/// Assemblies referenced directly by the source module of the compilation.
/// </summary>
/// <remarks>
/// Aliases <see cref="_lazyAliasesOfReferencedAssemblies"/>[i] are of an assembly <see cref="_lazyReferencedAssemblies"/>[i].
/// </remarks>
private ImmutableArray<ImmutableArray<string>> _lazyAliasesOfReferencedAssemblies;
/// <summary>
/// Unified assemblies referenced directly by the source module of the compilation.
/// </summary>
......@@ -204,7 +192,7 @@ internal bool HasCircularReference
}
}
internal Dictionary<MetadataReference, ReferencedAssembly> ReferencedAssembliesMap
internal Dictionary<MetadataReference, int> ReferencedAssembliesMap
{
get
{
......@@ -278,6 +266,15 @@ internal ImmutableArray<TAssemblySymbol> ReferencedAssemblies
}
}
internal ImmutableArray<ImmutableArray<string>> AliasesOfReferencedAssemblies
{
get
{
AssertBound();
return _lazyAliasesOfReferencedAssemblies;
}
}
internal ImmutableArray<UnifiedAssembly<TAssemblySymbol>> UnifiedAssemblies
{
get
......@@ -304,6 +301,7 @@ internal void AssertUnbound()
Debug.Assert(_lazyReferencedModules.IsDefault);
Debug.Assert(_lazyReferencedModulesReferences.IsDefault);
Debug.Assert(_lazyReferencedAssemblies.IsDefault);
Debug.Assert(_lazyAliasesOfReferencedAssemblies.IsDefault);
Debug.Assert(_lazyUnifiedAssemblies.IsDefault);
Debug.Assert(_lazyCorLibraryOpt == null);
}
......@@ -320,10 +318,13 @@ internal void AssertBound()
Debug.Assert(!_lazyReferencedModules.IsDefault);
Debug.Assert(!_lazyReferencedModulesReferences.IsDefault);
Debug.Assert(!_lazyReferencedAssemblies.IsDefault);
Debug.Assert(!_lazyAliasesOfReferencedAssemblies.IsDefault);
Debug.Assert(!_lazyUnifiedAssemblies.IsDefault);
// lazyCorLibrary is null if the compilation is corlib
Debug.Assert(_lazyReferencedAssemblies.Length == 0 || _lazyCorLibraryOpt != null);
Debug.Assert(_lazyReferencedAssemblies.Length == _lazyAliasesOfReferencedAssemblies.Length);
}
[Conditional("DEBUG")]
......@@ -344,7 +345,7 @@ internal bool IsBound
/// Call only while holding <see cref="CommonReferenceManager.SymbolCacheAndReferenceManagerStateGuard"/>.
/// </summary>
internal void InitializeNoLock(
Dictionary<MetadataReference, ReferencedAssembly> referencedAssembliesMap,
Dictionary<MetadataReference, int> referencedAssembliesMap,
Dictionary<MetadataReference, int> referencedModulesMap,
IDictionary<string, MetadataReference> boundReferenceDirectiveMap,
ImmutableArray<MetadataReference> boundReferenceDirectives,
......@@ -354,6 +355,7 @@ internal bool IsBound
ImmutableArray<PEModule> referencedModules,
ImmutableArray<ModuleReferences<TAssemblySymbol>> referencedModulesReferences,
ImmutableArray<TAssemblySymbol> referencedAssemblies,
ImmutableArray<ImmutableArray<string>> aliasesOfReferencedAssemblies,
ImmutableArray<UnifiedAssembly<TAssemblySymbol>> unifiedAssemblies)
{
AssertUnbound();
......@@ -371,6 +373,7 @@ internal bool IsBound
_lazyReferencedModules = referencedModules;
_lazyReferencedModulesReferences = referencedModulesReferences;
_lazyReferencedAssemblies = referencedAssemblies;
_lazyAliasesOfReferencedAssemblies = aliasesOfReferencedAssemblies;
_lazyUnifiedAssemblies = unifiedAssemblies;
_lazyHasCircularReference = containsCircularReferences.ToThreeState();
......@@ -381,45 +384,55 @@ internal bool IsBound
#region Compilation APIs Implementation
// for testing purposes
internal IEnumerable<string> ExternAliases
internal IEnumerable<string> ExternAliases => AliasesOfReferencedAssemblies.SelectMany(aliases => aliases);
internal sealed override IEnumerable<KeyValuePair<MetadataReference, IAssemblySymbol>> GetReferencedAssemblies()
{
get
{
return ReferencedAssembliesMap.Values.SelectMany(entry => entry.Aliases);
}
return ReferencedAssembliesMap.Select(ra => KeyValuePair.Create(ra.Key, (IAssemblySymbol)ReferencedAssemblies[ra.Value]));
}
internal sealed override IEnumerable<KeyValuePair<MetadataReference, IAssemblySymbol>> GetReferencedAssemblies()
internal TAssemblySymbol GetReferencedAssemblySymbol(MetadataReference reference)
{
return ReferencedAssembliesMap.Select(ra => KeyValuePair.Create(ra.Key, (IAssemblySymbol)ra.Value.Symbol));
int index;
return ReferencedAssembliesMap.TryGetValue(reference, out index) ? ReferencedAssemblies[index] : null;
}
internal sealed override bool TryGetReferencedAssemblySymbol(MetadataReference reference, out IAssemblySymbol symbol, out ImmutableArray<string> aliases)
internal int GetReferencedModuleIndex(MetadataReference reference)
{
ReferencedAssembly result;
if (ReferencedAssembliesMap.TryGetValue(reference, out result))
int index;
return ReferencedModuleIndexMap.TryGetValue(reference, out index) ? index : -1;
}
/// <summary>
/// Gets the <see cref="MetadataReference"/> that corresponds to the assembly symbol.
/// </summary>
internal override MetadataReference GetMetadataReference(IAssemblySymbol assemblySymbol)
{
foreach (var entry in ReferencedAssembliesMap)
{
symbol = result.Symbol;
aliases = result.Aliases;
return true;
if ((object)ReferencedAssemblies[entry.Value] == assemblySymbol)
{
return entry.Key;
}
}
symbol = null;
aliases = default(ImmutableArray<string>);
return false;
return null;
}
internal TAssemblySymbol GetReferencedAssemblySymbol(MetadataReference reference)
internal override IEnumerable<ValueTuple<IAssemblySymbol, ImmutableArray<string>>> GetReferencedAssemblyAliases()
{
ReferencedAssembly result;
return ReferencedAssembliesMap.TryGetValue(reference, out result) ? result.Symbol : null;
for (int i = 0; i < ReferencedAssemblies.Length; i++)
{
yield return ValueTuple.Create((IAssemblySymbol)ReferencedAssemblies[i], AliasesOfReferencedAssemblies[i]);
}
}
internal int GetReferencedModuleIndex(MetadataReference reference)
public bool DeclarationsAccessibleWithoutAlias(int referencedAssemblyIndex)
{
int index;
return ReferencedModuleIndexMap.TryGetValue(reference, out index) ? index : -1;
var aliases = AliasesOfReferencedAssemblies[referencedAssemblyIndex];
return aliases.Length == 0 || aliases.IndexOf(MetadataReferenceProperties.GlobalAlias, StringComparer.Ordinal) >= 0;
}
#endregion
}
}
......@@ -18,7 +18,7 @@ internal sealed class ModuleReferences<TAssemblySymbol>
/// <remarks>
/// Names[i] is the identity of assembly Symbols[i].
/// </remarks>
public readonly ImmutableArray<AssemblyIdentity> Names;
public readonly ImmutableArray<AssemblyIdentity> Identities;
/// <summary>
/// Assembly symbols that the identities are resolved against.
......@@ -36,16 +36,16 @@ internal sealed class ModuleReferences<TAssemblySymbol>
public readonly ImmutableArray<UnifiedAssembly<TAssemblySymbol>> UnifiedAssemblies;
public ModuleReferences(
ImmutableArray<AssemblyIdentity> names,
ImmutableArray<AssemblyIdentity> identities,
ImmutableArray<TAssemblySymbol> symbols,
ImmutableArray<UnifiedAssembly<TAssemblySymbol>> unifiedAssemblies)
{
Debug.Assert(!names.IsDefault);
Debug.Assert(!identities.IsDefault);
Debug.Assert(!symbols.IsDefault);
Debug.Assert(names.Length == symbols.Length);
Debug.Assert(identities.Length == symbols.Length);
Debug.Assert(!unifiedAssemblies.IsDefault);
this.Names = names;
this.Identities = identities;
this.Symbols = symbols;
this.UnifiedAssemblies = unifiedAssemblies;
}
......
......@@ -5,6 +5,7 @@
using System.Collections.Immutable;
using System.Diagnostics;
using Roslyn.Utilities;
using Microsoft.CodeAnalysis.Collections;
namespace Microsoft.CodeAnalysis
{
......@@ -416,5 +417,41 @@ public void AddMany(T item, int count)
Add(item);
}
}
public void RemoveDuplicates()
{
var set = PooledHashSet<T>.GetInstance();
int j = 0;
for (int i = 0; i < Count; i++)
{
if (set.Add(this[i]))
{
this[j] = this[i];
j++;
}
}
Clip(j);
set.Free();
}
public ImmutableArray<S> SelectDistinct<S>(Func<T, S> selector)
{
var result = ArrayBuilder<S>.GetInstance(Count);
var set = PooledHashSet<S>.GetInstance();
foreach (var item in this)
{
var selected = selector(item);
if (set.Add(selected))
{
result.Add(selected);
}
}
set.Free();
return result.ToImmutableAndFree();
}
}
}
......@@ -51,6 +51,9 @@
<Compile Include="..\..\Helpers\AbstractAnalyzerAssemblyLoader.cs">
<Link>AbstractAnalyzerAssemblyLoader.cs</Link>
</Compile>
<Compile Include="..\..\Helpers\AnalyzerAssemblyLoadUtils.cs">
<Link>AnalyzerAssemblyLoadUtils.cs</Link>
</Compile>
<Compile Include="..\..\Helpers\ShadowCopyAnalyzerAssemblyLoader.cs">
<Link>ShadowCopyAnalyzerAssemblyLoader.cs</Link>
</Compile>
......
......@@ -11,6 +11,8 @@
using System.Reflection.PortableExecutable;
using Roslyn.Utilities;
using static Microsoft.CodeAnalysis.AnalyzerAssemblyLoadUtils;
namespace Microsoft.CodeAnalysis
{
internal abstract class AbstractAnalyzerAssemblyLoader : IAnalyzerAssemblyLoader
......@@ -148,41 +150,5 @@ private bool FileMatchesAssemblyName(string path, string assemblySimpleName)
{
return Path.GetFileNameWithoutExtension(path).Equals(assemblySimpleName, StringComparison.OrdinalIgnoreCase);
}
private static AssemblyIdentity TryGetAssemblyIdentity(string filePath)
{
try
{
if (!File.Exists(filePath))
{
return null;
}
using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete))
using (var peReader = new PEReader(stream))
{
var metadataReader = peReader.GetMetadataReader();
AssemblyDefinition assemblyDefinition = metadataReader.GetAssemblyDefinition();
string name = metadataReader.GetString(assemblyDefinition.Name);
Version version = assemblyDefinition.Version;
StringHandle cultureHandle = assemblyDefinition.Culture;
string cultureName = (!cultureHandle.IsNil) ? metadataReader.GetString(cultureHandle) : null;
AssemblyFlags flags = assemblyDefinition.Flags;
bool hasPublicKey = (flags & AssemblyFlags.PublicKey) != 0;
BlobHandle publicKeyHandle = assemblyDefinition.PublicKey;
ImmutableArray<byte> publicKeyOrToken = !publicKeyHandle.IsNil
? metadataReader.GetBlobBytes(publicKeyHandle).AsImmutableOrNull()
: default(ImmutableArray<byte>);
return new AssemblyIdentity(name, version, cultureName, publicKeyOrToken, hasPublicKey);
}
}
catch { }
return null;
}
}
}
// 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.Immutable;
using System.IO;
using System.Reflection;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
namespace Microsoft.CodeAnalysis
{
internal static class AnalyzerAssemblyLoadUtils
{
public static AssemblyIdentity TryGetAssemblyIdentity(string filePath)
{
try
{
using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete))
using (var peReader = new PEReader(stream))
{
var metadataReader = peReader.GetMetadataReader();
AssemblyDefinition assemblyDefinition = metadataReader.GetAssemblyDefinition();
string name = metadataReader.GetString(assemblyDefinition.Name);
Version version = assemblyDefinition.Version;
StringHandle cultureHandle = assemblyDefinition.Culture;
string cultureName = (!cultureHandle.IsNil) ? metadataReader.GetString(cultureHandle) : null;
AssemblyFlags flags = assemblyDefinition.Flags;
bool hasPublicKey = (flags & AssemblyFlags.PublicKey) != 0;
BlobHandle publicKeyHandle = assemblyDefinition.PublicKey;
ImmutableArray<byte> publicKeyOrToken = !publicKeyHandle.IsNil
? metadataReader.GetBlobBytes(publicKeyHandle).AsImmutableOrNull()
: default(ImmutableArray<byte>);
return new AssemblyIdentity(name, version, cultureName, publicKeyOrToken, hasPublicKey);
}
}
catch { }
return null;
}
}
}
// 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.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
using Roslyn.Utilities;
using static Microsoft.CodeAnalysis.AnalyzerAssemblyLoadUtils;
namespace Microsoft.CodeAnalysis
{
/// Core CLR compatible wrapper for loading analyzers.
internal sealed class CoreClrAnalyzerAssemblyLoader : AssemblyLoadContext, IAnalyzerAssemblyLoader
{
private readonly Dictionary<string, Assembly> _pathsToAssemblies = new Dictionary<string, Assembly>(StringComparer.OrdinalIgnoreCase);
private readonly Dictionary<string, Assembly> _namesToAssemblies = new Dictionary<string, Assembly>();
private readonly List<string> _dependencyPaths = new List<string>();
private readonly object _guard = new object();
/// <summary>
/// Creates a new instance of <see cref="CoreClrAnalyzerAssemblyLoader" />,
/// sets that instance to be the default <see cref="AssemblyLoadContext" />,
/// and returns that instance. Throws if the Default is already set or the
/// binding model is already locked.
/// </summary>
public static CoreClrAnalyzerAssemblyLoader CreateAndSetDefault()
{
var assemblyLoader = new CoreClrAnalyzerAssemblyLoader();
InitializeDefaultContext(assemblyLoader);
return assemblyLoader;
}
public void AddDependencyLocation(string fullPath)
{
if (fullPath == null)
{
throw new ArgumentNullException(nameof(fullPath));
}
lock (_guard)
{
_dependencyPaths.Add(fullPath);
}
}
public Assembly LoadFromPath(string fullPath)
{
if (fullPath == null)
{
throw new ArgumentNullException(nameof(fullPath));
}
Debug.Assert(PathUtilities.IsAbsolute(fullPath));
lock (_guard)
{
Assembly assembly;
if (_pathsToAssemblies.TryGetValue(fullPath, out assembly))
{
return assembly;
}
return LoadAndCache(fullPath);
}
}
private static readonly string[] s_extensions = new string[] { ".dll", ".exe" };
/// <summary>
/// Searches and loads from the base directory of the current
/// app context
/// </summary>
private Assembly AppContextLoad(AssemblyName assemblyName)
{
var baseDir = AppContext.BaseDirectory;
foreach (var extension in s_extensions)
{
var path = Path.Combine(baseDir, assemblyName.Name + extension);
if (File.Exists(path))
{
lock (_guard)
{
return LoadAndCache(path);
}
}
}
return null;
}
protected override Assembly Load(AssemblyName assemblyName)
{
lock (_guard)
{
// Try and grab assembly using standard load
Assembly assembly = AppContextLoad(assemblyName);
if (assembly != null)
{
return assembly;
}
string fullName = assemblyName.FullName;
if (_namesToAssemblies.TryGetValue(fullName, out assembly))
{
return assembly;
}
AssemblyIdentity requestedIdentity;
if (!AssemblyIdentity.TryParseDisplayName(fullName, out requestedIdentity))
{
return null;
}
foreach (var candidatePath in _dependencyPaths)
{
if (IsAssemblyAlreadyLoaded(candidatePath) ||
!FileMatchesAssemblyName(candidatePath, requestedIdentity.Name))
{
continue;
}
var candidateIdentity = TryGetAssemblyIdentity(candidatePath);
if (requestedIdentity.Equals(candidateIdentity))
{
return LoadAndCache(candidatePath);
}
}
return null;
}
}
/// <remarks>
/// Assumes we have a lock on _guard
/// </remarks>
private Assembly LoadAndCache(string fullPath)
{
var assembly = LoadFromAssemblyPath(fullPath);
var name = assembly.FullName;
_pathsToAssemblies[fullPath] = assembly;
_namesToAssemblies[name] = assembly;
return assembly;
}
private bool IsAssemblyAlreadyLoaded(string path)
{
return _pathsToAssemblies.ContainsKey(path);
}
private bool FileMatchesAssemblyName(string path, string assemblySimpleName)
{
return Path.GetFileNameWithoutExtension(path).Equals(assemblySimpleName, StringComparison.OrdinalIgnoreCase);
}
}
}
// 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.Reflection;
namespace Microsoft.CodeAnalysis
{
/// <summary>
/// Workaround for assembly loading in core clr -- this loader does nothing.
/// </summary>
internal sealed class NoOpAnalyzerAssemblyLoader : IAnalyzerAssemblyLoader
{
public Assembly LoadFromPath(string fullPath) => null;
public void AddDependencyLocation(string fullPath) { }
}
}
......@@ -1227,7 +1227,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
''' Gets the <see cref="MetadataReference"/> that corresponds to the assembly symbol.
''' </summary>
Friend Shadows Function GetMetadataReference(assemblySymbol As AssemblySymbol) As MetadataReference
Return Me.GetBoundReferenceManager().ReferencedAssembliesMap.Where(Function(kvp) kvp.Value.Symbol Is assemblySymbol).Select(Function(kvp) kvp.Key).FirstOrDefault()
Return Me.GetBoundReferenceManager().GetMetadataReference(assemblySymbol)
End Function
Public Overrides ReadOnly Property ReferencedAssemblyNames As IEnumerable(Of AssemblyIdentity)
......@@ -2640,15 +2640,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Get
End Property
Protected Overrides Function CommonGetMetadataReference(_assemblySymbol As IAssemblySymbol) As MetadataReference
Dim symbol = TryCast(_assemblySymbol, AssemblySymbol)
If symbol IsNot Nothing Then
Return Me.GetMetadataReference(symbol)
Else
Return Nothing
End If
End Function
Protected Overrides Function CommonGetEntryPoint(cancellationToken As CancellationToken) As IMethodSymbol
Return Me.GetEntryPoint(cancellationToken)
End Function
......
......@@ -44,7 +44,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
''' </summary>
Friend NotOverridable Overrides Function GetReferencedAssemblies() As ImmutableArray(Of AssemblyIdentity)
AssertReferencesInitialized()
Return _moduleReferences.Names
Return _moduleReferences.Identities
End Function
''' <summary>
......
......@@ -141,7 +141,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
' Given compilation is the first compilation that shares this manager and its symbols are requested.
' Perform full reference resolution and binding.
If Not IsBound AndAlso CreateSourceAssemblyFullBind(compilation) Then
If Not IsBound AndAlso CreateAndSetSourceAssemblyFullBind(compilation) Then
' we have successfully bound the references for the compilation
......@@ -158,7 +158,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
' NOTE: The CreateSourceAssemblyFullBind is going to replace compilation's reference manager with newManager.
Dim newManager = New ReferenceManager(Me.SimpleAssemblyName, Me.IdentityComparer, Me.ObservedMetadata)
Dim successful = newManager.CreateSourceAssemblyFullBind(compilation)
Dim successful = newManager.CreateAndSetSourceAssemblyFullBind(compilation)
' The new manager isn't shared with any other compilation so there is no other
' thread but the current one could have initialized it.
......@@ -253,11 +253,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Sub
' Returns false if another compilation sharing this manager finished binding earlier and we should reuse its results.
Friend Function CreateSourceAssemblyFullBind(compilation As VisualBasicCompilation) As Boolean
Friend Function CreateAndSetSourceAssemblyFullBind(compilation As VisualBasicCompilation) As Boolean
Dim assemblySymbol As SourceAssemblySymbol
Dim referencedAssembliesMap As Dictionary(Of MetadataReference, ReferencedAssembly)
Dim referencedModulesMap As Dictionary(Of MetadataReference, Integer)
Dim boundReferenceDirectiveMap As IDictionary(Of String, MetadataReference) = Nothing
Dim boundReferenceDirectives As ImmutableArray(Of MetadataReference) = Nothing
Dim hasCircularReference As Boolean
......@@ -316,10 +313,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Else
Dim fileData = DirectCast(allAssemblies(i), AssemblyDataForFile)
bindingResult(i).AssemblySymbol = New Symbols.Metadata.PE.PEAssemblySymbol(fileData.Assembly,
fileData.DocumentationProvider,
fileData.IsLinked,
fileData.EffectiveImportOptions)
bindingResult(i).AssemblySymbol = New PEAssemblySymbol(fileData.Assembly,
fileData.DocumentationProvider,
fileData.IsLinked,
fileData.EffectiveImportOptions)
End If
newSymbols.Add(i)
......@@ -328,7 +325,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Debug.Assert(allAssemblies(i).IsLinked = bindingResult(i).AssemblySymbol.IsLinked)
Next
assemblySymbol = New SourceAssemblySymbol(compilation, SimpleAssemblyName, compilation.MakeSourceModuleName(), modules)
Dim assemblySymbol = New SourceAssemblySymbol(compilation, SimpleAssemblyName, compilation.MakeSourceModuleName(), modules)
Dim corLibrary As AssemblySymbol
......@@ -360,31 +357,32 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
InitializeNewSymbols(newSymbols, assemblySymbol, allAssemblies, bindingResult, missingAssemblies)
End If
' Setup references for the compilation
referencedAssembliesMap = New Dictionary(Of MetadataReference, ReferencedAssembly)(referenceMap.Length)
referencedModulesMap = New Dictionary(Of MetadataReference, Integer)(modules.Length)
Dim sourceModule = assemblySymbol.SourceModule
Dim referencedAssemblySymbols = sourceModule.GetReferencedAssemblySymbols()
' Calculate reference maps And aliases
Dim referencedAssembliesMap = New Dictionary(Of MetadataReference, Integer)(referenceMap.Length)
Dim referencedModulesMap = New Dictionary(Of MetadataReference, Integer)(modules.Length)
Dim aliasesOfReferencedAssembliesBuilder = ArrayBuilder(Of ImmutableArray(Of String)).GetInstance(referencedAssemblies.Length)
For i As Integer = 0 To referenceMap.Length - 1 Step 1
If referenceMap(i).IsSkipped Then
Continue For
End If
If referenceMap(i).Kind = MetadataImageKind.Module Then
' add 1 for the manifest module
Dim moduleIndex = 1 + referenceMap(i).Index
referencedModulesMap.Add(references(i), moduleIndex)
referencedAssembliesMap.Add(references(i), New ReferencedAssembly(assemblySymbol, aliases:=ImmutableArray(Of String).Empty))
Else
' index into assembly data array
Dim assemblyIndex = referenceMap(i).Index
referencedAssembliesMap.Add(references(i), New ReferencedAssembly(referencedAssemblySymbols(assemblyIndex), aliases:=ImmutableArray(Of String).Empty))
Debug.Assert(aliasesOfReferencedAssembliesBuilder.Count = assemblyIndex)
referencedAssembliesMap.Add(references(i), assemblyIndex)
aliasesOfReferencedAssembliesBuilder.Add(ImmutableArray(Of String).Empty)
End If
Next
Dim aliasesOfReferencedAssemblies = aliasesOfReferencedAssembliesBuilder.ToImmutableAndFree()
If compilation._lazyAssemblySymbol Is Nothing Then
SyncLock SymbolCacheAndReferenceManagerStateGuard
If compilation._lazyAssemblySymbol Is Nothing Then
......@@ -407,8 +405,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
If(corLibrary Is assemblySymbol, Nothing, corLibrary),
modules,
moduleReferences,
referencedAssemblySymbols,
sourceModule.GetUnifiedAssemblies())
assemblySymbol.SourceModule.GetReferencedAssemblySymbols(),
aliasesOfReferencedAssemblies,
assemblySymbol.SourceModule.GetUnifiedAssemblies())
' Make sure that the given compilation holds on this instance of reference manager.
Debug.Assert(compilation._referenceManager Is Me OrElse hasCircularReference)
......@@ -445,7 +444,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End If
Next
Dim linkedReferencedAssemblies As New List(Of AssemblySymbol)()
Dim linkedReferencedAssembliesBuilder = ArrayBuilder(Of AssemblySymbol).GetInstance()
' Setup CorLibrary and NoPia stuff for newly created assemblies
......@@ -456,28 +455,30 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End If
' Setup linked referenced assemblies.
linkedReferencedAssemblies.Clear()
linkedReferencedAssembliesBuilder.Clear()
If assemblies(i).IsLinked Then
linkedReferencedAssemblies.Add(bindingResult(i).AssemblySymbol)
linkedReferencedAssembliesBuilder.Add(bindingResult(i).AssemblySymbol)
End If
For Each referenceBinding In bindingResult(i).ReferenceBinding
If referenceBinding.IsBound AndAlso
assemblies(referenceBinding.DefinitionIndex).IsLinked Then
linkedReferencedAssemblies.Add(
linkedReferencedAssembliesBuilder.Add(
bindingResult(referenceBinding.DefinitionIndex).AssemblySymbol)
End If
Next
If linkedReferencedAssemblies.Count > 0 Then
bindingResult(i).AssemblySymbol.SetLinkedReferencedAssemblies(
ImmutableArray.CreateRange(Of AssemblySymbol)(linkedReferencedAssemblies.Distinct()))
If linkedReferencedAssembliesBuilder.Count > 0 Then
linkedReferencedAssembliesBuilder.RemoveDuplicates()
bindingResult(i).AssemblySymbol.SetLinkedReferencedAssemblies(linkedReferencedAssembliesBuilder.ToImmutable())
End If
bindingResult(i).AssemblySymbol.SetCorLibrary(corLibrary)
Next
linkedReferencedAssembliesBuilder.Free()
If missingAssemblies IsNot Nothing Then
For Each missingAssembly In missingAssemblies.Values
missingAssembly.SetCorLibrary(corLibrary)
......@@ -687,9 +688,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Inherits AssemblyData
Private _assemblies As List(Of AssemblySymbol)
Protected m_Identity As AssemblyIdentity
Protected m_ReferencedAssemblies As ImmutableArray(Of AssemblyIdentity)
Protected ReadOnly m_EmbedInteropTypes As Boolean
Private ReadOnly m_Identity As AssemblyIdentity
Private ReadOnly m_ReferencedAssemblies As ImmutableArray(Of AssemblyIdentity)
Private ReadOnly m_EmbedInteropTypes As Boolean
'This is the name of the compilation that is being built.
'This should be the assembly name w/o the extension. It is
......@@ -697,8 +698,17 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
'assembly will give friend access to the compilation.
Protected ReadOnly m_CompilationName As String
Protected Sub New(embedInteropTypes As Boolean, compilationName As String)
Protected Sub New(identity As AssemblyIdentity,
referencedAssemblies As ImmutableArray(Of AssemblyIdentity),
embedInteropTypes As Boolean,
compilationName As String)
Debug.Assert(identity IsNot Nothing)
Debug.Assert(Not referencedAssemblies.IsDefault)
m_EmbedInteropTypes = embedInteropTypes
m_Identity = identity
m_ReferencedAssemblies = referencedAssemblies
m_CompilationName = compilationName
End Sub
......@@ -732,7 +742,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Property
Public Overrides Function BindAssemblyReferences(assemblies As ImmutableArray(Of AssemblyData), assemblyIdentityComparer As AssemblyIdentityComparer) As AssemblyReferenceBinding()
Return ReferenceManager.ResolveReferencedAssemblies(m_ReferencedAssemblies, assemblies, assemblyIdentityComparer, okToResolveAgainstCompilationBeingCreated:=True)
Return ResolveReferencedAssemblies(m_ReferencedAssemblies, assemblies, assemblyIdentityComparer, okToResolveAgainstCompilationBeingCreated:=True)
End Function
Public NotOverridable Overrides ReadOnly Property IsLinked As Boolean
......@@ -778,15 +788,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
compilationName As String,
compilationImportOptions As MetadataImportOptions)
MyBase.New(embedInteropTypes, compilationName)
MyBase.New(assembly.Identity, assembly.AssemblyReferences, embedInteropTypes, compilationName)
Debug.Assert(cachedSymbols IsNot Nothing)
Debug.Assert(assembly IsNot Nothing)
_cachedSymbols = cachedSymbols
_assembly = assembly
m_Identity = assembly.Identity
m_ReferencedAssemblies = assembly.AssemblyReferences
_documentationProvider = If(documentationProvider, DocumentationProvider.Default)
_compilationImportOptions = compilationImportOptions
......@@ -822,7 +829,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
' accessing cached symbols requires a lock
SyncLock SymbolCacheAndReferenceManagerStateGuard
For Each assemblySymbol In _cachedSymbols
Dim peAssembly = TryCast(assemblySymbol, Symbols.Metadata.PE.PEAssemblySymbol)
Dim peAssembly = TryCast(assemblySymbol, PEAssemblySymbol)
If IsMatchingAssembly(peAssembly) Then
assemblies.Add(peAssembly)
End If
......@@ -831,10 +838,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Sub
Public Overrides Function IsMatchingAssembly(candidateAssembly As AssemblySymbol) As Boolean
Return IsMatchingAssembly(TryCast(candidateAssembly, Symbols.Metadata.PE.PEAssemblySymbol))
Return IsMatchingAssembly(TryCast(candidateAssembly, PEAssemblySymbol))
End Function
Private Overloads Function IsMatchingAssembly(peAssembly As Symbols.Metadata.PE.PEAssemblySymbol) As Boolean
Private Overloads Function IsMatchingAssembly(peAssembly As PEAssemblySymbol) As Boolean
If peAssembly Is Nothing Then
Return False
End If
......@@ -880,57 +887,46 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Private NotInheritable Class AssemblyDataForCompilation
Inherits AssemblyDataForMetadataOrCompilation
Private ReadOnly _compilation As VisualBasicCompilation
Public ReadOnly Property Compilation As VisualBasicCompilation
Get
Return _compilation
End Get
End Property
Public ReadOnly Compilation As VisualBasicCompilation
Public Sub New(compilation As VisualBasicCompilation, embedInteropTypes As Boolean)
MyBase.New(embedInteropTypes, compilation.AssemblyName)
MyBase.New(compilation.Assembly.Identity, GetReferencedAssemblies(compilation), embedInteropTypes, compilation.AssemblyName)
Debug.Assert(compilation IsNot Nothing)
_compilation = compilation
Dim assembly As AssemblySymbol = compilation.Assembly
m_Identity = assembly.Identity
Me.Compilation = compilation
End Sub
Private Shared Function GetReferencedAssemblies(compilation As VisualBasicCompilation) As ImmutableArray(Of AssemblyIdentity)
' Collect information about references
Dim refs = ArrayBuilder(Of AssemblyIdentity).GetInstance()
Dim modules = assembly.Modules
Dim mCount As Integer = modules.Length
Dim i As Integer
Dim modules = compilation.Assembly.Modules
' Filter out linked assemblies referenced by the source module.
Dim sourceReferencedAssemblies = modules(0).GetReferencedAssemblies()
Dim sourceReferencedAssemblySymbols = modules(0).GetReferencedAssemblySymbols()
Dim rCount As Integer = sourceReferencedAssemblies.Length
Debug.Assert(rCount = sourceReferencedAssemblySymbols.Length)
Debug.Assert(sourceReferencedAssemblies.Length = sourceReferencedAssemblySymbols.Length)
For i = 0 To rCount - 1 Step 1
For i = 0 To sourceReferencedAssemblies.Length - 1
If Not sourceReferencedAssemblySymbols(i).IsLinked Then
refs.Add(sourceReferencedAssemblies(i))
End If
Next
For i = 1 To mCount - 1 Step 1
For i = 1 To modules.Length - 1
refs.AddRange(modules(i).GetReferencedAssemblies())
Next
m_ReferencedAssemblies = refs.ToImmutableAndFree()
End Sub
Return refs.ToImmutableAndFree()
End Function
Protected Overrides Sub AddAvailableSymbols(assemblies As List(Of AssemblySymbol))
assemblies.Add(_compilation.Assembly)
assemblies.Add(Compilation.Assembly)
' accessing cached symbols requires a lock
SyncLock SymbolCacheAndReferenceManagerStateGuard
_compilation.AddRetargetingAssemblySymbolsNoLock(assemblies)
Compilation.AddRetargetingAssemblySymbolsNoLock(assemblies)
End SyncLock
End Sub
......@@ -946,8 +942,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Debug.Assert(Not (TypeOf asm Is Retargeting.RetargetingAssemblySymbol))
Return asm Is _compilation.Assembly
Return asm Is Compilation.Assembly
End Function
Public Overrides ReadOnly Property ContainsNoPiaLocalTypes As Boolean
......@@ -958,13 +953,13 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Public Overrides ReadOnly Property DeclaresTheObjectClass As Boolean
Get
Return _compilation.DeclaresTheObjectClass
Return Compilation.DeclaresTheObjectClass
End Get
End Property
Public Overrides ReadOnly Property SourceCompilation As Compilation
Get
Return _compilation
Return Compilation
End Get
End Property
End Class
......
......@@ -170,7 +170,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols.Retargeting
Dim underlyingBoundReferences As ImmutableArray(Of AssemblySymbol) = _underlyingModule.GetReferencedAssemblySymbols()
Dim referencedAssemblySymbols As ImmutableArray(Of AssemblySymbol) = moduleReferences.Symbols
Dim referencedAssemblies As ImmutableArray(Of AssemblyIdentity) = moduleReferences.Names
Dim referencedAssemblies As ImmutableArray(Of AssemblyIdentity) = moduleReferences.Identities
Debug.Assert(referencedAssemblySymbols.Length = referencedAssemblies.Length)
Debug.Assert(referencedAssemblySymbols.Length <= underlyingBoundReferences.Length) ' Linked references are filtered out.
......
......@@ -12,6 +12,6 @@ public static int Main(string[] args)
=> Vbc.Run(args: args,
clientDirectory: AppContext.BaseDirectory,
sdkDirectory: @"C:\Windows\Microsoft.NET\Framework\v4.0.30319",
analyzerLoader: new NoOpAnalyzerAssemblyLoader());
analyzerLoader: CoreClrAnalyzerAssemblyLoader.CreateAndSetDefault());
}
}
......@@ -67,8 +67,11 @@
<Compile Include="..\..\Helpers\ConsoleUtil.cs">
<Link>ConsoleUtil.cs</Link>
</Compile>
<Compile Include="..\..\Helpers\NoOpAnalyzerAssemblyLoader.cs">
<Link>ConsoleUtil.cs</Link>
<Compile Include="..\..\Helpers\CoreClrAnalyzerAssemblyLoader.cs">
<Link>CoreClrAnalyzerAssemblyLoader.cs</Link>
</Compile>
<Compile Include="..\..\Helpers\AnalyzerAssemblyLoadUtils.cs">
<Link>AnalyzerAssemblyLoadUtils.cs</Link>
</Compile>
<Compile Include="Vbc.cs" />
<Compile Include="Program.cs" />
......
......@@ -23,9 +23,11 @@
"System.Runtime.Extensions": "4.0.11-beta-23321",
"System.Runtime.Handles": "4.0.1-beta-23321",
"System.Runtime.InteropServices": "4.0.21-beta-23321",
"System.Security.Cryptography.Hashing.Algorithms": "4.0.0-beta-23311",
"System.Runtime.Loader": "4.0.0-beta-23321",
"System.Runtime.Serialization.Json": "4.0.1-beta-23321",
"System.Security.Cryptography.Hashing.Algorithms": "4.0.0-beta-23311",
"System.Text.Encoding": "4.0.11-beta-23321",
"System.Text.Encoding.CodePages": "4.0.1-beta-23321",
"System.Text.Encoding.Extensions": "4.0.11-beta-23321",
"System.Threading": "4.0.11-beta-23321",
"System.Threading.Tasks": "4.0.11-beta-23321",
......
......@@ -478,6 +478,19 @@
"lib/DNXCore50/System.Runtime.InteropServices.dll": {}
}
},
"System.Runtime.Loader/4.0.0-beta-23321": {
"dependencies": {
"System.IO": "[4.0.0, )",
"System.Reflection": "[4.0.0, )",
"System.Runtime": "[4.0.0, )"
},
"compile": {
"ref/dotnet/System.Runtime.Loader.dll": {}
},
"runtime": {
"lib/DNXCore50/System.Runtime.Loader.dll": {}
}
},
"System.Runtime.Serialization.Json/4.0.1-beta-23321": {
"dependencies": {
"System.Private.DataContractSerialization": "[4.0.1-beta-23321, )"
......@@ -569,6 +582,15 @@
"lib/DNXCore50/System.Text.Encoding.dll": {}
}
},
"System.Text.Encoding.CodePages/4.0.1-beta-23321": {
"dependencies": {
"System.Runtime": "[4.0.0, )",
"System.Text.Encoding": "[4.0.10, )"
},
"compile": {
"ref/dotnet/System.Text.Encoding.CodePages.dll": {}
}
},
"System.Text.Encoding.Extensions/4.0.11-beta-23321": {
"dependencies": {
"System.Runtime": "[4.0.0, )",
......@@ -927,6 +949,27 @@
"lib/dotnet/System.Private.Uri.dll": {}
}
},
"runtime.unix.System.Text.Encoding.CodePages/4.0.1-beta-23321": {
"dependencies": {
"System.Collections": "[4.0.10, )",
"System.Globalization": "[4.0.10, )",
"System.IO": "[4.0.10, )",
"System.Reflection": "[4.0.10, )",
"System.Resources.ResourceManager": "[4.0.0, )",
"System.Runtime": "[4.0.20, )",
"System.Runtime.Extensions": "[4.0.10, )",
"System.Runtime.Handles": "[4.0.0, )",
"System.Runtime.InteropServices": "[4.0.20, )",
"System.Text.Encoding": "[4.0.10, )",
"System.Threading": "[4.0.10, )"
},
"compile": {
"ref/dotnet/_._": {}
},
"runtime": {
"lib/dotnet/System.Text.Encoding.CodePages.dll": {}
}
},
"runtime.unix.System.Threading/4.0.11-beta-23321": {
"compile": {
"ref/dotnet/_._": {}
......@@ -1391,6 +1434,19 @@
"lib/DNXCore50/System.Runtime.InteropServices.dll": {}
}
},
"System.Runtime.Loader/4.0.0-beta-23321": {
"dependencies": {
"System.IO": "[4.0.0, )",
"System.Reflection": "[4.0.0, )",
"System.Runtime": "[4.0.0, )"
},
"compile": {
"ref/dotnet/System.Runtime.Loader.dll": {}
},
"runtime": {
"lib/DNXCore50/System.Runtime.Loader.dll": {}
}
},
"System.Runtime.Serialization.Json/4.0.1-beta-23321": {
"dependencies": {
"System.Private.DataContractSerialization": "[4.0.1-beta-23321, )"
......@@ -1482,6 +1538,15 @@
"lib/DNXCore50/System.Text.Encoding.dll": {}
}
},
"System.Text.Encoding.CodePages/4.0.1-beta-23321": {
"dependencies": {
"System.Runtime": "[4.0.0, )",
"System.Text.Encoding": "[4.0.10, )"
},
"compile": {
"ref/dotnet/System.Text.Encoding.CodePages.dll": {}
}
},
"System.Text.Encoding.Extensions/4.0.11-beta-23321": {
"dependencies": {
"System.Runtime": "[4.0.0, )",
......@@ -2002,6 +2067,27 @@
"lib/DNXCore50/System.Runtime.Extensions.dll": {}
}
},
"runtime.win7.System.Text.Encoding.CodePages/4.0.1-beta-23321": {
"dependencies": {
"System.Collections": "[4.0.10, )",
"System.Globalization": "[4.0.10, )",
"System.IO": "[4.0.10, )",
"System.Reflection": "[4.0.10, )",
"System.Resources.ResourceManager": "[4.0.0, )",
"System.Runtime": "[4.0.20, )",
"System.Runtime.Extensions": "[4.0.10, )",
"System.Runtime.Handles": "[4.0.0, )",
"System.Runtime.InteropServices": "[4.0.20, )",
"System.Text.Encoding": "[4.0.10, )",
"System.Threading": "[4.0.10, )"
},
"compile": {
"ref/dotnet/_._": {}
},
"runtime": {
"runtimes/win7/lib/dotnet/System.Text.Encoding.CodePages.dll": {}
}
},
"runtime.win7.System.Threading/4.0.11-beta-23321": {
"compile": {
"ref/dotnet/_._": {}
......@@ -2466,6 +2552,19 @@
"lib/DNXCore50/System.Runtime.InteropServices.dll": {}
}
},
"System.Runtime.Loader/4.0.0-beta-23321": {
"dependencies": {
"System.IO": "[4.0.0, )",
"System.Reflection": "[4.0.0, )",
"System.Runtime": "[4.0.0, )"
},
"compile": {
"ref/dotnet/System.Runtime.Loader.dll": {}
},
"runtime": {
"lib/DNXCore50/System.Runtime.Loader.dll": {}
}
},
"System.Runtime.Serialization.Json/4.0.1-beta-23321": {
"dependencies": {
"System.Private.DataContractSerialization": "[4.0.1-beta-23321, )"
......@@ -2557,6 +2656,15 @@
"lib/DNXCore50/System.Text.Encoding.dll": {}
}
},
"System.Text.Encoding.CodePages/4.0.1-beta-23321": {
"dependencies": {
"System.Runtime": "[4.0.0, )",
"System.Text.Encoding": "[4.0.10, )"
},
"compile": {
"ref/dotnet/System.Text.Encoding.CodePages.dll": {}
}
},
"System.Text.Encoding.Extensions/4.0.11-beta-23321": {
"dependencies": {
"System.Runtime": "[4.0.0, )",
......@@ -2975,6 +3083,18 @@
"runtime.unix.System.Private.Uri.nuspec"
]
},
"runtime.unix.System.Text.Encoding.CodePages/4.0.1-beta-23321": {
"sha512": "ZZS7hqjzl5l0xtJzr/WmK+4Q2Vrr3RcI0KjCNARH2GT2Zcj0Hsnm1Fd+5M9eOg36YbSjy3ZNVn7JbH/Q7ioPEA==",
"type": "Package",
"files": [
"[Content_Types].xml",
"_rels/.rels",
"lib/dotnet/System.Text.Encoding.CodePages.dll",
"package/services/metadata/core-properties/3da52d6f11ac4de8b21b1c4988e87d14.psmdcp",
"ref/dotnet/_._",
"runtime.unix.System.Text.Encoding.CodePages.nuspec"
]
},
"runtime.unix.System.Threading/4.0.11-beta-23321": {
"sha512": "QlIzt08mk+SpmK8PuZJA+H0UfgAurvw5vRcAQImrVxKezS+ILuQ3YTkwQ/Q79koGHfgeFjWMdjYCSGY2KrfVDQ==",
"type": "Package",
......@@ -3385,6 +3505,31 @@
"runtimes/win8-aot/lib/netcore50/zh-hant/System.Runtime.Extensions.xml"
]
},
"runtime.win7.System.Text.Encoding.CodePages/4.0.1-beta-23321": {
"sha512": "0XPZ3FG5C/jV/uzM7YY9ZcdbBMyU3Bh1VmT3v0/EaTQllb9r7+oTy2egWyCdgiFDDKpdfiERVw9EJGQQA3nTDA==",
"type": "Package",
"files": [
"[Content_Types].xml",
"_rels/.rels",
"lib/win8/_._",
"lib/wp8/_._",
"lib/wpa81/_._",
"package/services/metadata/core-properties/b4379f524aba4b37927aad12501a01d3.psmdcp",
"ref/dotnet/_._",
"runtime.win7.System.Text.Encoding.CodePages.nuspec",
"runtimes/win7/lib/dotnet/de/System.Text.Encoding.CodePages.xml",
"runtimes/win7/lib/dotnet/es/System.Text.Encoding.CodePages.xml",
"runtimes/win7/lib/dotnet/fr/System.Text.Encoding.CodePages.xml",
"runtimes/win7/lib/dotnet/it/System.Text.Encoding.CodePages.xml",
"runtimes/win7/lib/dotnet/ja/System.Text.Encoding.CodePages.xml",
"runtimes/win7/lib/dotnet/ko/System.Text.Encoding.CodePages.xml",
"runtimes/win7/lib/dotnet/ru/System.Text.Encoding.CodePages.xml",
"runtimes/win7/lib/dotnet/System.Text.Encoding.CodePages.dll",
"runtimes/win7/lib/dotnet/System.Text.Encoding.CodePages.xml",
"runtimes/win7/lib/dotnet/zh-hans/System.Text.Encoding.CodePages.xml",
"runtimes/win7/lib/dotnet/zh-hant/System.Text.Encoding.CodePages.xml"
]
},
"runtime.win7.System.Threading/4.0.11-beta-23321": {
"sha512": "9S9vqzTsHTp59g7TSJEBUbG7fgZoSM9i1bbP7QWzksILC+ga7Uw8cgg6G/TSgYoCDc8m0gylokUJRFevDyQJbg==",
"type": "Package",
......@@ -4581,6 +4726,18 @@
"System.Runtime.InteropServices.nuspec"
]
},
"System.Runtime.Loader/4.0.0-beta-23321": {
"sha512": "xyfQB/CKuzy/kaiMWtNgX16mMTsgt2ktdmG7COIXBFAkHUARSeBAjMOWkGdNWPzOWINYumqamA8JxGsQlPhuPQ==",
"type": "Package",
"files": [
"[Content_Types].xml",
"_rels/.rels",
"lib/DNXCore50/System.Runtime.Loader.dll",
"package/services/metadata/core-properties/55d60ad8f5d24e06bf703dd426e1ec45.psmdcp",
"ref/dotnet/System.Runtime.Loader.dll",
"System.Runtime.Loader.nuspec"
]
},
"System.Runtime.Serialization.Json/4.0.1-beta-23321": {
"sha512": "TWQRwFnriFMykVgsCyowKFI5eLWoceMtoIrrx9Wd2ZL+XAnsdiYe8OUVeL9Q0kLVs3Ew12sPiXtY2wvVDAYR3w==",
"type": "Package",
......@@ -4758,6 +4915,26 @@
"System.Text.Encoding.nuspec"
]
},
"System.Text.Encoding.CodePages/4.0.1-beta-23321": {
"sha512": "2wTRNrgvdymVYnGfQJFf28UX8N+JipXBZjdLMoecCw5eIVel7ffKYlzQKFbHFmZ8RIxLsjhsr1oEn542acsd/Q==",
"type": "Package",
"files": [
"[Content_Types].xml",
"_rels/.rels",
"lib/MonoAndroid10/_._",
"lib/MonoTouch10/_._",
"lib/xamarinios10/_._",
"lib/xamarinmac20/_._",
"package/services/metadata/core-properties/ea1d25d85d6a4287a5f88d11ba69be14.psmdcp",
"ref/dotnet/System.Text.Encoding.CodePages.dll",
"ref/MonoAndroid10/_._",
"ref/MonoTouch10/_._",
"ref/xamarinios10/_._",
"ref/xamarinmac20/_._",
"runtime.json",
"System.Text.Encoding.CodePages.nuspec"
]
},
"System.Text.Encoding.Extensions/4.0.11-beta-23321": {
"sha512": "DfR8dxgjAyrPeFGLG+O9mLvC5eP76hMMLrOsBMqVBnfwxSa/TYjlNfjluR+bHI/qQZ/W0JELViC93lNX9LGsSQ==",
"type": "Package",
......@@ -5138,9 +5315,11 @@
"System.Runtime.Extensions >= 4.0.11-beta-23321",
"System.Runtime.Handles >= 4.0.1-beta-23321",
"System.Runtime.InteropServices >= 4.0.21-beta-23321",
"System.Runtime.Loader >= 4.0.0-beta-23321",
"System.Runtime.Serialization.Json >= 4.0.1-beta-23321",
"System.Security.Cryptography.Hashing.Algorithms >= 4.0.0-beta-23311",
"System.Text.Encoding >= 4.0.11-beta-23321",
"System.Text.Encoding.CodePages >= 4.0.1-beta-23321",
"System.Text.Encoding.Extensions >= 4.0.11-beta-23321",
"System.Threading >= 4.0.11-beta-23321",
"System.Threading.Tasks >= 4.0.11-beta-23321",
......
......@@ -72,6 +72,9 @@
<Compile Include="..\..\Helpers\AbstractAnalyzerAssemblyLoader.cs">
<Link>AbstractAnalyzerAssemblyLoader.cs</Link>
</Compile>
<Compile Include="..\..\Helpers\AnalyzerAssemblyLoadUtils.cs">
<Link>AnalyzerAssemblyLoadUtils.cs</Link>
</Compile>
<Compile Include="..\..\Helpers\ConsoleUtil.cs">
<Link>ConsoleUtil.cs</Link>
</Compile>
......
......@@ -15,7 +15,8 @@ public partial class AddAwaitTests : AbstractCSharpDiagnosticProviderBasedUserDi
public void BadAsyncReturnOperand1()
{
var initial =
@"using System.Threading.Tasks;
@"using System;
using System.Threading.Tasks;
class Program
{
......@@ -31,7 +32,8 @@ async Task<int> Test2()
}";
var expected =
@"using System.Threading.Tasks;
@"using System;
using System.Threading.Tasks;
class Program
{
......@@ -48,11 +50,261 @@ async Task<int> Test2()
Test(initial, expected);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)]
public void BadAsyncReturnOperand_WithLeadingTrivia1()
{
var initial =
@"using System;
using System.Threading.Tasks;
class Program
{
async Task<int> Test()
{
return 3;
}
async Task<int> Test2()
{
return
// Useful comment
[|Test()|];
}
}";
var expected =
@"using System;
using System.Threading.Tasks;
class Program
{
async Task<int> Test()
{
return 3;
}
async Task<int> Test2()
{
return
// Useful comment
await Test();
}
}";
Test(initial, expected, compareTokens: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)]
public void BadAsyncReturnOperand_ConditionalExpressionWithTrailingTrivia_SingleLine()
{
var initial =
@"using System;
using System.Threading.Tasks;
class Program
{
async Task<int> Test() => 3;
async Task<int> Test2()
{[|
return true ? Test() /* true */ : Test() /* false */;
|]}
}";
var expected =
@"using System;
using System.Threading.Tasks;
class Program
{
async Task<int> Test() => 3;
async Task<int> Test2()
{
return await (true ? Test() /* true */ : Test() /* false */);
}
}";
Test(initial, expected, compareTokens: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)]
public void BadAsyncReturnOperand_ConditionalExpressionWithTrailingTrivia_Multiline()
{
var initial =
@"using System;
using System.Threading.Tasks;
class Program
{
async Task<int> Test() => 3;
async Task<int> Test2()
{[|
return true ? Test() // aaa
: Test() // bbb
;
|]}
}";
var expected =
@"using System;
using System.Threading.Tasks;
class Program
{
async Task<int> Test() => 3;
async Task<int> Test2()
{
return await (true ? Test() // aaa
: Test()) // bbb
;
}
}";
Test(initial, expected, compareTokens: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)]
public void BadAsyncReturnOperand_NullCoalescingExpressionWithTrailingTrivia_SingleLine()
{
var initial =
@"using System;
using System.Threading.Tasks;
class Program
{
async Task<int> Test() => 3;
async Task<int> Test2()
{[|
return null /* 0 */ ?? Test() /* 1 */;
|]}
}";
var expected =
@"using System;
using System.Threading.Tasks;
class Program
{
async Task<int> Test() => 3;
async Task<int> Test2()
{
return await (null /* 0 */ ?? Test() /* 1 */);
}
}";
Test(initial, expected, compareTokens: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)]
public void BadAsyncReturnOperand_NullCoalescingExpressionWithTrailingTrivia_Multiline()
{
var initial =
@"using System;
using System.Threading.Tasks;
class Program
{
async Task<int> Test() => 3;
async Task<int> Test2()
{[|
return null // aaa
?? Test() // bbb
;
|]}
}";
var expected =
@"using System;
using System.Threading.Tasks;
class Program
{
async Task<int> Test() => 3;
async Task<int> Test2()
{
return await (null // aaa
?? Test()) // bbb
;
}
}";
Test(initial, expected, compareTokens: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)]
public void BadAsyncReturnOperand_AsExpressionWithTrailingTrivia_SingleLine()
{
var initial =
@"using System;
using System.Threading.Tasks;
class Program
{
async Task<int> Test2()
{[|
return null /* 0 */ as Task<int> /* 1 */;
|]}
}";
var expected =
@"using System;
using System.Threading.Tasks;
class Program
{
async Task<int> Test2()
{
return await (null /* 0 */ as Task<int> /* 1 */);
}
}";
Test(initial, expected, compareTokens: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)]
public void BadAsyncReturnOperand_AsExpressionWithTrailingTrivia_Multiline()
{
var initial =
@"using System;
using System.Threading.Tasks;
class Program
{
async Task<int> Test() => 3;
async Task<int> Test2()
{[|
return null // aaa
as Task<int> // bbb
;
|]}
}";
var expected =
@"using System;
using System.Threading.Tasks;
class Program
{
async Task<int> Test() => 3;
async Task<int> Test2()
{
return await (null // aaa
as Task<int>) // bbb
;
}
}";
Test(initial, expected, compareTokens: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)]
public void TaskNotAwaited()
{
var initial =
@"using System.Threading.Tasks;
@"using System;
using System.Threading.Tasks;
class Program
{
async void Test()
......@@ -62,7 +314,8 @@ async void Test()
}";
var expected =
@"using System.Threading.Tasks;
@"using System;
using System.Threading.Tasks;
class Program
{
async void Test()
......@@ -73,11 +326,43 @@ async void Test()
Test(initial, expected);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)]
public void TaskNotAwaited_WithLeadingTrivia()
{
var initial =
@"using System;
using System.Threading.Tasks;
class Program
{
async void Test()
{
// Useful comment
[|Task.Delay(3);|]
}
}";
var expected =
@"using System;
using System.Threading.Tasks;
class Program
{
async void Test()
{
// Useful comment
await Task.Delay(3);
}
}";
Test(initial, expected, compareTokens: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)]
public void FunctionNotAwaited()
{
var initial =
@"using System.Threading.Tasks;
@"using System;
using System.Threading.Tasks;
class Program
{
Task AwaitableFunction()
......@@ -92,7 +377,8 @@ async void Test()
}";
var expected =
@"using System.Threading.Tasks;
@"using System;
using System.Threading.Tasks;
class Program
{
Task AwaitableFunction()
......@@ -108,6 +394,88 @@ async void Test()
Test(initial, expected);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)]
public void FunctionNotAwaited_WithLeadingTrivia()
{
var initial =
@"using System;
using System.Threading.Tasks;
class Program
{
Task AwaitableFunction()
{
return Task.FromResult(true);
}
async void Test()
{
// Useful comment
[|AwaitableFunction();|]
}
}";
var expected =
@"using System;
using System.Threading.Tasks;
class Program
{
Task AwaitableFunction()
{
return Task.FromResult(true);
}
async void Test()
{
// Useful comment
await AwaitableFunction();
}
}";
Test(initial, expected, compareTokens: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)]
public void FunctionNotAwaited_WithLeadingTrivia1()
{
var initial =
@"using System;
using System.Threading.Tasks;
class Program
{
Task AwaitableFunction()
{
return Task.FromResult(true);
}
async void Test()
{
var i = 0;
[|AwaitableFunction();|]
}
}";
var expected =
@"using System;
using System.Threading.Tasks;
class Program
{
Task AwaitableFunction()
{
return Task.FromResult(true);
}
async void Test()
{
var i = 0;
await AwaitableFunction();
}
}";
Test(initial, expected, compareTokens: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)]
public void TestAssignmentExpression()
{
......@@ -199,6 +567,30 @@ public void TestAssignmentExpression8()
@"using System ; using System . Threading . Tasks ; class TestClass { private async Task MyTestMethod1Async ( ) { Func < Task > @delegate = delegate { int myInt = MyIntM [||] ethodAsync ( ) ; } ; } private Task < int > MyIntMethodAsync ( ) { return Task . FromResult ( result : 1 ) ; } } ");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)]
public void TestTernaryOperator()
{
Test(
@"using System ; using System . Threading . Tasks ; class Program { async Task < int > A ( ) { return [|true ? Task . FromResult ( 0 ) : Task . FromResult ( 1 )|] ; } } ",
@"using System ; using System . Threading . Tasks ; class Program { async Task < int > A ( ) { return await ( true ? Task . FromResult ( 0 ) : Task . FromResult ( 1 ) ) ; } } ");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)]
public void TestNullCoalescingOperator()
{
Test(
@"using System ; using System . Threading . Tasks ; class Program { async Task < int > A ( ) { return [|null ?? Task . FromResult ( 1 )|] } } ",
@"using System ; using System . Threading . Tasks ; class Program { async Task < int > A ( ) { return await ( null ?? Task . FromResult ( 1 ) ) } } ");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)]
public void TestAsExpression()
{
Test(
@"using System ; using System . Threading . Tasks ; class Program { async Task < int > A ( ) { return [|null as Task < int >|] } } ",
@"using System ; using System . Threading . Tasks ; class Program { async Task < int > A ( ) { return await ( null as Task < int > ) } } ");
}
internal override Tuple<DiagnosticAnalyzer, CodeFixProvider> CreateDiagnosticProviderAndFixer(Workspace workspace)
{
return new Tuple<DiagnosticAnalyzer, CodeFixProvider>(null, new CSharpAddAwaitCodeFixProvider());
......
......@@ -4,7 +4,7 @@ Imports Microsoft.CodeAnalysis.CodeFixes
Imports Microsoft.CodeAnalysis.Diagnostics
Imports Microsoft.CodeAnalysis.VisualBasic.CodeFixes.Async
Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics.AddAsync
Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics.Async
Public Class AddAsyncTests
Inherits AbstractVisualBasicDiagnosticProviderBasedUserDiagnosticTest
......
......@@ -5,7 +5,7 @@ Imports Microsoft.CodeAnalysis.Diagnostics
Imports Microsoft.CodeAnalysis.VisualBasic.CodeFixes.Async
Imports Roslyn.Test.Utilities
Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics.AddAsync
Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics.Async
Public Class AddAwaitTests
Inherits AbstractVisualBasicDiagnosticProviderBasedUserDiagnosticTest
......@@ -17,6 +17,35 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics.AddAsy
)
End Sub
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)>
Public Sub TaskNotAwaited_WithLeadingTrivia()
Dim initial =
<File>
Imports System
Imports System.Threading.Tasks
Module Program
Async Sub M()
' Useful comment
[|Task.Delay(3)|]
End Sub
End Module
</File>
Dim expected =
<File>
Imports System
Imports System.Threading.Tasks
Module Program
Async Sub M()
' Useful comment
Await Task.Delay(3)
End Sub
End Module
</File>
Test(initial, expected, compareTokens:=False)
End Sub
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)>
Public Sub BadAsyncReturnOperand1()
Dim initial =
......@@ -96,6 +125,50 @@ End Module
Test(initial, expected)
End Sub
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)>
Public Sub FunctionNotAwaited_WithLeadingTrivia()
Dim initial =
<File>
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Threading.Tasks
Module Program
Function AwaitableFunction() As Task
Return New Task()
End Function
Async Sub MySub()
' Useful comment
[|AwaitableFunction()|]
End Sub
End Module
</File>
Dim expected =
<File>
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Threading.Tasks
Module Program
Function AwaitableFunction() As Task
Return New Task()
End Function
Async Sub MySub()
' Useful comment
Await AwaitableFunction()
End Sub
End Module
</File>
Test(initial, expected, compareTokens:=False)
End Sub
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)>
Public Sub SubLambdaNotAwaited()
Dim initial =
......@@ -144,6 +217,7 @@ Imports System.Threading.Tasks
Module Program
Sub MySub()
Dim a = Async Function()
' Useful comment
[|Task.Delay(1)|]
End Function
End Sub
......@@ -159,13 +233,14 @@ Imports System.Threading.Tasks
Module Program
Sub MySub()
Dim a = Async Function()
' Useful comment
Await Task.Delay(1)
End Function
End Sub
End Module
</File>
Test(initial, expected)
Test(initial, expected, compareTokens:=False)
End Sub
<Fact(), Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)>
......@@ -216,6 +291,27 @@ NewLines("Imports System.Threading.Tasks \n Module Program \n Sub MyTestMethod1A
NewLines("Imports System.Threading.Tasks \n Module Program \n Sub MyTestMethod1Async() \n Dim myInt As Long \n Dim lambda = Async Sub() myInt = Await MyIntMethodAsync() \n End Sub \n Private Function MyIntMethodAsync() As Task(Of Object) \n Return Task.FromResult(New Object()) \n End Function \n End Module"))
End Sub
<Fact(), Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)>
Public Sub TestTernaryOperator()
Test(
NewLines("Imports System.Threading.Tasks \n Module M \n Async Function A() As Task(Of Integer) \n Return [|If(True, Task.FromResult(0), Task.FromResult(1))|] \n End Function \n End Module"),
NewLines("Imports System.Threading.Tasks \n Module M \n Async Function A() As Task(Of Integer) \n Return Await If(True, Task.FromResult(0), Task.FromResult(1)) \n End Function \n End Module"))
End Sub
<Fact(), Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)>
Public Sub TestTernaryOperator2()
Test(
NewLines("Imports System.Threading.Tasks \n Module M \n Async Function A() As Task(Of Integer) \n Return [|If(Nothing, Task.FromResult(1))|] \n End Function \n End Module"),
NewLines("Imports System.Threading.Tasks \n Module M \n Async Function A() As Task(Of Integer) \n Return Await If(Nothing, Task.FromResult(1)) \n End Function \n End Module"))
End Sub
<Fact(), Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)>
Public Sub TestCastExpression()
Test(
NewLines("Imports System.Threading.Tasks \n Module M \n Async Function A() As Task(Of Integer) \n Return [|TryCast(Nothing, Task(Of Integer))|] \n End Function \n End Module"),
NewLines("Imports System.Threading.Tasks \n Module M \n Async Function A() As Task(Of Integer) \n Return Await TryCast(Nothing, Task(Of Integer)) \n End Function \n End Module"))
End Sub
Friend Overrides Function CreateDiagnosticProviderAndFixer(workspace As Workspace) As Tuple(Of DiagnosticAnalyzer, CodeFixProvider)
Return Tuple.Create(Of DiagnosticAnalyzer, CodeFixProvider)(
Nothing,
......
......@@ -4,7 +4,7 @@ Imports Microsoft.CodeAnalysis.CodeFixes
Imports Microsoft.CodeAnalysis.Diagnostics
Imports Microsoft.CodeAnalysis.VisualBasic.CodeFixes.Async
Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics.AddAsync
Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics.Async
Public Class ChangeToAsyncTests
Inherits AbstractVisualBasicDiagnosticProviderBasedUserDiagnosticTest
......
......@@ -91,6 +91,7 @@
<Compile Include="ExpansionTests.cs" />
<Compile Include="FormatSpecifierTests.cs" />
<Compile Include="FullNameTests.cs" />
<Compile Include="FunctionPointerTests.cs" />
<Compile Include="Helpers\TestTypeExtensions.cs" />
<Compile Include="NativeViewTests.cs" />
<Compile Include="ObjectIdTests.cs" />
......
// 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 Microsoft.CodeAnalysis.ExpressionEvaluator;
using Microsoft.VisualStudio.Debugger.Clr;
using Microsoft.VisualStudio.Debugger.Evaluation;
using System;
using System.Diagnostics;
using Xunit;
using Type = Microsoft.VisualStudio.Debugger.Metadata.Type;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
public class FunctionPointerTests : CSharpResultProviderTestBase
{
[Fact]
public void Root()
{
const int ptr = 0x1234;
var value = CreateDkmClrValue(ptr, type: new DkmClrType(FunctionPointerType.Instance));
var evalResult = FormatResult("pfn", value);
Verify(evalResult,
EvalResult("pfn", PointerToString(new IntPtr(ptr)), "System.Object*", "pfn", DkmEvaluationResultFlags.None, DkmEvaluationResultCategory.Other));
}
[Fact]
public void Member()
{
var source =
@"class C
{
object pfn;
}";
const int ptr = 0x0;
GetMemberValueDelegate getMemberValue = (v, m) => (m == "pfn") ? CreateDkmClrValue(ptr, type: new DkmClrType(FunctionPointerType.Instance)) : null;
var runtime = new DkmClrRuntimeInstance(ReflectionUtilities.GetMscorlibAndSystemCore(GetAssembly(source)), getMemberValue: getMemberValue);
using (runtime.Load())
{
var type = runtime.GetType("C");
var value = CreateDkmClrValue(type.Instantiate(), type: type);
var evalResult = FormatResult("o", value);
Verify(evalResult,
EvalResult("o", "{C}", "C", "o", DkmEvaluationResultFlags.Expandable, DkmEvaluationResultCategory.Other));
var children = GetChildren(evalResult);
Verify(children,
EvalResult("pfn", PointerToString(new IntPtr(ptr)), "object {System.Object*}", "o.pfn", DkmEvaluationResultFlags.None, DkmEvaluationResultCategory.Other));
}
}
// Function pointer type has IsPointer == true and GetElementType() == null.
private sealed class FunctionPointerType : TypeImpl
{
internal static readonly FunctionPointerType Instance = new FunctionPointerType();
private FunctionPointerType() : base(typeof(object).MakePointerType())
{
Debug.Assert(this.IsPointer);
}
public override Type GetElementType()
{
return null;
}
}
}
}
......@@ -38,9 +38,9 @@ internal sealed class MemberExpansion : Expansion
}
var runtimeType = type.GetLmrType();
// Primitives, enums and null values with a declared type that is an interface have no visible members.
// Primitives, enums, function pointers, and null values with a declared type that is an interface have no visible members.
Debug.Assert(!runtimeType.IsInterface || value.IsNull);
if (formatter.IsPredefinedType(runtimeType) || runtimeType.IsEnum || runtimeType.IsInterface)
if (formatter.IsPredefinedType(runtimeType) || runtimeType.IsEnum || runtimeType.IsInterface || runtimeType.IsFunctionPointer())
{
return null;
}
......
......@@ -61,9 +61,15 @@ internal string GetTypeName(TypeAndCustomInfo typeAndInfo, bool escapeKeywordIde
int pointerCount = 0;
while (type.IsPointer)
{
var elementType = type.GetElementType();
if (elementType == null)
{
// Null for function pointers.
break;
}
index++;
pointerCount++;
type = type.GetElementType();
type = elementType;
}
int nullableCount = 0;
......
namespace Microsoft.VisualStudio.Debugger.Metadata
{
// Starting in Visual Studio 2015, Update 1, a new api exists to detect if a type is a function pointer.
// This placeholder method is a temporary shim to allow Roslyn to avoid taking a dependency on Update 1 debugger
// binaries until Update 1 ships. See https://github.com/dotnet/roslyn/issues/5428.
internal static class DebuggerMetadataExtensions
{
public static bool IsFunctionPointer(this Type type)
{
// Note: The Visual Studio 2015 RTM version of Microsoft.VisualStudio.Debugger.Metadata.dll does not support function pointers at all,
// so when running against the RTM version of that dll, this method will always return false. Against the update 1 version,
// we can exploit the fact that the only time a pointer will ever have a null element type will be function pointers.
//
// Using this shim, rather than simply calling Type.IsFunctionPointer() allows the Update 1 expression evaluator to continue
// to work against the RTM debugger.
return type.IsPointer && type.GetElementType() == null;
}
}
}
\ No newline at end of file
......@@ -831,6 +831,12 @@ private void GetEvaluationResultsAndContinue(ArrayBuilder<EvalResultDataItem> ro
return null;
}
if(declaredType.IsFunctionPointer())
{
// Function pointers have no expansion
return null;
}
if (declaredType.IsPointer)
{
// If this ever happens, the element type info is just .SkipOne().
......
......@@ -13,6 +13,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Formatter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Formatter.TypeNames.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Formatter.Values.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Helpers\DebuggerPlaceholders.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Helpers\DynamicFlagsCustomTypeInfo_Factory.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Helpers\TypeAndCustomInfo.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Helpers\TypeWalker.cs" />
......
......@@ -11,11 +11,11 @@
namespace Microsoft.CodeAnalysis.ExpressionEvaluator
{
internal sealed class TypeImpl : Type
internal class TypeImpl : Type
{
internal readonly System.Type Type;
private TypeImpl(System.Type type)
internal TypeImpl(System.Type type)
{
Debug.Assert(type != null);
this.Type = type;
......
......@@ -3,16 +3,18 @@
using System;
using System.Collections.Immutable;
using System.Composition;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CodeFixes.Async;
using Microsoft.CodeAnalysis.CSharp.Extensions;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Formatting;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.Simplification;
using Roslyn.Utilities;
using Resources = Microsoft.CodeAnalysis.CSharp.CSharpFeaturesResources;
using Microsoft.CodeAnalysis.LanguageServices;
using System.Linq;
namespace Microsoft.CodeAnalysis.CSharp.CodeFixes.Async
{
......@@ -20,12 +22,12 @@ namespace Microsoft.CodeAnalysis.CSharp.CodeFixes.Async
internal class CSharpAddAwaitCodeFixProvider : AbstractAddAsyncAwaitCodeFixProvider
{
/// <summary>
/// Since this is an async method, the return expression must be of type 'blah' rather than 'baz'
/// Because this call is not awaited, execution of the current method continues before the call is completed.
/// </summary>
private const string CS4014 = "CS4014";
/// <summary>
/// Because this call is not awaited, execution of the current method continues before the call is completed.
/// Since this is an async method, the return expression must be of type 'blah' rather than 'baz'
/// </summary>
private const string CS4016 = "CS4016";
......@@ -48,15 +50,14 @@ internal class CSharpAddAwaitCodeFixProvider : AbstractAddAsyncAwaitCodeFixProvi
CancellationToken cancellationToken)
{
var expression = oldNode as ExpressionSyntax;
if (expression == null)
{
return SpecializedTasks.Default<SyntaxNode>();
}
switch (diagnostic.Id)
{
case CS4014:
if (expression == null)
{
return Task.FromResult<SyntaxNode>(null);
}
return Task.FromResult(root.ReplaceNode(oldNode, ConvertToAwaitExpression(expression)));
case CS4016:
......@@ -74,33 +75,27 @@ internal class CSharpAddAwaitCodeFixProvider : AbstractAddAsyncAwaitCodeFixProvi
}
return Task.FromResult(root.ReplaceNode(oldNode, ConvertToAwaitExpression(expression)));
default:
return SpecializedTasks.Default<SyntaxNode>();
}
}
private static bool DoesExpressionReturnTask(ExpressionSyntax expression, SemanticModel semanticModel)
{
if (expression == null)
INamedTypeSymbol taskType = null;
if (!TryGetTaskType(semanticModel, out taskType))
{
return false;
}
INamedTypeSymbol taskType = null;
INamedTypeSymbol returnType = null;
return TryGetTaskAndExpressionTypes(expression, semanticModel, out taskType, out returnType) &&
return TryGetExpressionType(expression, semanticModel, out returnType) &&
semanticModel.Compilation.ClassifyConversion(taskType, returnType).Exists;
}
private static bool DoesExpressionReturnGenericTaskWhoseArgumentsMatchLeftSide(ExpressionSyntax expression, SemanticModel semanticModel, Project project, CancellationToken cancellationToken)
{
if (expression == null)
{
return false;
}
if (!IsInAsyncFunction(expression))
{
return false;
......@@ -108,7 +103,8 @@ private static bool DoesExpressionReturnGenericTaskWhoseArgumentsMatchLeftSide(E
INamedTypeSymbol taskType = null;
INamedTypeSymbol rightSideType = null;
if (!TryGetTaskAndExpressionTypes(expression, semanticModel, out taskType, out rightSideType))
if (!TryGetTaskType(semanticModel, out taskType) ||
!TryGetExpressionType(expression, semanticModel, out rightSideType))
{
return false;
}
......@@ -119,7 +115,7 @@ private static bool DoesExpressionReturnGenericTaskWhoseArgumentsMatchLeftSide(E
return false;
}
if(!rightSideType.IsGenericType)
if (!rightSideType.IsGenericType)
{
return false;
}
......@@ -150,11 +146,23 @@ private static bool IsInAsyncFunction(ExpressionSyntax expression)
return false;
}
private static ExpressionSyntax ConvertToAwaitExpression(ExpressionSyntax expression)
private static SyntaxNode ConvertToAwaitExpression(ExpressionSyntax expression)
{
return SyntaxFactory.AwaitExpression(expression)
if ((expression is BinaryExpressionSyntax || expression is ConditionalExpressionSyntax) && expression.HasTrailingTrivia)
{
var expWithTrailing = expression.WithoutLeadingTrivia();
var span = expWithTrailing.GetLocation().GetLineSpan().Span;
if (span.Start.Line == span.End.Line && !expWithTrailing.DescendantTrivia().Any(trivia => trivia.IsKind(SyntaxKind.SingleLineCommentTrivia)))
{
return SyntaxFactory.AwaitExpression(SyntaxFactory.ParenthesizedExpression(expWithTrailing))
.WithLeadingTrivia(expression.GetLeadingTrivia())
.WithAdditionalAnnotations(Formatter.Annotation);
}
}
return SyntaxFactory.AwaitExpression(expression.WithoutTrivia().Parenthesize())
.WithTriviaFrom(expression)
.WithAdditionalAnnotations(Formatter.Annotation);
.WithAdditionalAnnotations(Simplifier.Annotation, Formatter.Annotation);
}
}
}
......@@ -4,7 +4,6 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.Internal.Log;
namespace Microsoft.CodeAnalysis.CodeFixes.Async
{
......@@ -28,38 +27,21 @@ protected override async Task<CodeAction> GetCodeFix(SyntaxNode root, SyntaxNode
return null;
}
protected static bool TryGetTaskAndExpressionTypes(
protected static bool TryGetExpressionType(
SyntaxNode expression,
SemanticModel semanticModel,
out INamedTypeSymbol source,
out INamedTypeSymbol destination)
out INamedTypeSymbol returnType)
{
source = null;
destination = null;
var info = semanticModel.GetSymbolInfo(expression);
var methodSymbol = info.Symbol as IMethodSymbol;
if (methodSymbol == null)
{
return false;
}
var typeInfo = semanticModel.GetTypeInfo(expression);
returnType = typeInfo.Type as INamedTypeSymbol;
return returnType != null;
}
protected static bool TryGetTaskType(SemanticModel semanticModel, out INamedTypeSymbol taskType)
{
var compilation = semanticModel.Compilation;
var taskType = compilation.GetTypeByMetadataName("System.Threading.Tasks.Task");
if (taskType == null)
{
return false;
}
var returnType = methodSymbol.ReturnType as INamedTypeSymbol;
if (returnType == null)
{
return false;
}
source = taskType;
destination = returnType;
return true;
taskType = compilation.GetTypeByMetadataName("System.Threading.Tasks.Task");
return taskType != null;
}
private class MyCodeAction : CodeAction.DocumentChangeAction
......
......@@ -8,6 +8,7 @@ Imports Microsoft.CodeAnalysis.CodeFixes
Imports Microsoft.CodeAnalysis.CodeFixes.Async
Imports Microsoft.CodeAnalysis.Formatting
Imports Microsoft.CodeAnalysis.LanguageServices
Imports Microsoft.CodeAnalysis.Simplification
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports Resources = Microsoft.CodeAnalysis.VisualBasic.VBFeaturesResources.VBFeaturesResources
......@@ -35,40 +36,37 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.Async
Protected Overrides Function GetNewRoot(root As SyntaxNode, oldNode As SyntaxNode, semanticModel As SemanticModel, diagnostic As Diagnostic, document As Document, cancellationToken As CancellationToken) As Task(Of SyntaxNode)
Dim expression = TryCast(oldNode, ExpressionSyntax)
If expression Is Nothing Then
Return SpecializedTasks.Default(Of SyntaxNode)()
End If
Select Case diagnostic.Id
Case BC30311
If Not DoesExpressionReturnGenericTaskWhoseArgumentsMatchLeftSide(expression, semanticModel, document.Project, cancellationToken) Then
Return Task.FromResult(Of SyntaxNode)(Nothing)
End If
Return Task.FromResult(root.ReplaceNode(oldNode, ConverToAwaitExpression(expression)))
Return Task.FromResult(root.ReplaceNode(oldNode, ConverToAwaitExpression(expression, semanticModel, cancellationToken)))
Case BC37055
If Not DoesExpressionReturnTask(expression, semanticModel) Then
Return Task.FromResult(Of SyntaxNode)(Nothing)
End If
Return Task.FromResult(root.ReplaceNode(oldNode, ConverToAwaitExpression(expression)))
Return Task.FromResult(root.ReplaceNode(oldNode, ConverToAwaitExpression(expression, semanticModel, cancellationToken)))
Case BC42358
If expression Is Nothing Then
Return Task.FromResult(Of SyntaxNode)(Nothing)
End If
Return Task.FromResult(root.ReplaceNode(oldNode, ConverToAwaitExpression(expression)))
Return Task.FromResult(root.ReplaceNode(oldNode, ConverToAwaitExpression(expression, semanticModel, cancellationToken)))
Case Else
Return Task.FromResult(Of SyntaxNode)(Nothing)
Return SpecializedTasks.Default(Of SyntaxNode)()
End Select
End Function
Private Function DoesExpressionReturnGenericTaskWhoseArgumentsMatchLeftSide(expression As ExpressionSyntax, semanticModel As SemanticModel, project As Project, cancellationToken As CancellationToken) As Boolean
If expression Is Nothing Then
Return False
End If
If Not IsInAsyncBlock(expression) Then
Return False
End If
Dim taskType As INamedTypeSymbol = Nothing
Dim rightSideType As INamedTypeSymbol = Nothing
If Not TryGetTaskAndExpressionTypes(expression, semanticModel, taskType, rightSideType) Then
If Not TryGetTaskType(semanticModel, taskType) OrElse
Not TryGetExpressionType(expression, semanticModel, rightSideType) Then
Return False
End If
......@@ -109,18 +107,17 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.Async
End Function
Private Function DoesExpressionReturnTask(expression As ExpressionSyntax, semanticModel As SemanticModel) As Boolean
If expression Is Nothing Then
Return Nothing
End If
Dim taskType As INamedTypeSymbol = Nothing
Dim returnType As INamedTypeSymbol = Nothing
Return TryGetTaskAndExpressionTypes(expression, semanticModel, taskType, returnType) AndAlso
Return TryGetTaskType(semanticModel, taskType) AndAlso
TryGetExpressionType(expression, semanticModel, returnType) AndAlso
semanticModel.Compilation.ClassifyConversion(taskType, returnType).Exists
End Function
Private Function ConverToAwaitExpression(expression As ExpressionSyntax) As ExpressionSyntax
Return SyntaxFactory.AwaitExpression(expression).WithAdditionalAnnotations(Formatter.Annotation)
Private Shared Function ConverToAwaitExpression(expression As ExpressionSyntax, semanticModel As SemanticModel, cancellationToken As CancellationToken) As ExpressionSyntax
Return SyntaxFactory.AwaitExpression(expression.WithoutTrivia().Parenthesize()) _
.WithTriviaFrom(expression) _
.WithAdditionalAnnotations(Simplifier.Annotation, Formatter.Annotation)
End Function
End Class
......
// 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.Threading;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Text;
......@@ -19,6 +20,8 @@ private CSharpScriptCompiler()
public override DiagnosticFormatter DiagnosticFormatter => CSharpDiagnosticFormatter.Instance;
public override StringComparer IdentifierComparer => StringComparer.Ordinal;
public override bool IsCompleteSubmission(SyntaxTree tree) => SyntaxFactory.IsCompleteSubmission(tree);
public override SyntaxTree ParseSubmission(SourceText text, CancellationToken cancellationToken) =>
......
......@@ -26,8 +26,8 @@ public class HostModel
public class InteractiveSessionTests : TestBase
{
private static readonly Assembly s_lazySystemRuntimeAssembly;
private static readonly Assembly SystemRuntimeAssembly = s_lazySystemRuntimeAssembly ?? (s_lazySystemRuntimeAssembly = Assembly.Load(new AssemblyName("System.Runtime, Version=4.0.20.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")));
private static readonly Assembly HostAssembly = typeof(InteractiveSessionTests).GetTypeInfo().Assembly;
internal static readonly Assembly SystemRuntimeAssembly = s_lazySystemRuntimeAssembly ?? (s_lazySystemRuntimeAssembly = Assembly.Load(new AssemblyName("System.Runtime, Version=4.0.20.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")));
internal static readonly Assembly HostAssembly = typeof(InteractiveSessionTests).GetTypeInfo().Assembly;
// TODO: shouldn't be needed
private static readonly ScriptOptions OptionsWithFacades = ScriptOptions.Default.AddReferences(SystemRuntimeAssembly);
......
......@@ -9,10 +9,16 @@
#pragma warning disable RS0003 // Do not directly await a Task
namespace Microsoft.CodeAnalysis.Scripting.CSharp.Test
namespace Microsoft.CodeAnalysis.Scripting.CSharp.UnitTests
{
public class ScriptTests : TestBase
{
public class Globals
{
public int X;
public int Y;
}
[Fact]
public void TestCreateScript()
{
......@@ -128,12 +134,6 @@ public void Do()
, ScriptOptions.Default.WithReferences(MscorlibRef, SystemRef, SystemCoreRef, CSharpRef));
}
public class Globals
{
public int X;
public int Y;
}
[Fact]
public async Task TestRunScriptWithGlobals()
{
......@@ -234,14 +234,68 @@ public void TestCreateMethodDelegate()
#endif
[Fact]
public async Task TestGetScriptVariableAfterRunningScript()
public async Task ScriptVariables_Chain()
{
var globals = new Globals { X = 10, Y = 20 };
var script =
CSharpScript.Create(
"var a = '1';",
options: ScriptOptions.Default.WithReferences(InteractiveSessionTests.SystemRuntimeAssembly),
globalsType: globals.GetType()).
ContinueWith("var b = 2u;").
ContinueWith("var a = 3m;").
ContinueWith("var x = a + b;").
ContinueWith("var X = Y;");
var state = await script.RunAsync(globals);
AssertEx.Equal(new[] { "a", "b", "a", "x", "X" }, state.Variables.Select(v => v.Name));
AssertEx.Equal(new object[] { '1', 2u, 3m, 5m, 20 }, state.Variables.Select(v => v.Value));
AssertEx.Equal(new Type[] { typeof(char), typeof(uint), typeof(decimal), typeof(decimal), typeof(int) }, state.Variables.Select(v => v.Type));
Assert.Equal(3m, state.GetVariable("a").Value);
Assert.Equal(2u, state.GetVariable("b").Value);
Assert.Equal(5m, state.GetVariable("x").Value);
Assert.Equal(20, state.GetVariable("X").Value);
Assert.Equal(null, state.GetVariable("A"));
Assert.Same(state.GetVariable("X"), state.GetVariable("X"));
}
[Fact]
public async Task ScriptVariable_SetValue()
{
var script = CSharpScript.Create("var x = 1;");
var s1 = await script.RunAsync();
s1.GetVariable("x").Value = 2;
Assert.Equal(2, s1.GetVariable("x").Value);
// rerunning the script from the beginning rebuilds the state:
var s2 = await s1.Script.RunAsync();
Assert.Equal(1, s2.GetVariable("x").Value);
// continuing preserves the state:
var s3 = await s1.ContinueWithAsync("x");
Assert.Equal(2, s3.GetVariable("x").Value);
Assert.Equal(2, s3.ReturnValue);
}
[Fact]
public async Task ScriptVariable_SetValue_Errors()
{
var state = await CSharpScript.RunAsync("int x = 100;");
var globals = state.Variables.Names.ToList();
Assert.Equal(1, globals.Count);
Assert.Equal(true, globals.Contains("x"));
Assert.Equal(true, state.Variables.ContainsVariable("x"));
Assert.Equal(100, (int)state.Variables["x"].Value);
var state = await CSharpScript.RunAsync(@"
var x = 1;
readonly var y = 2;
const int z = 3;
");
Assert.Throws<ArgumentException>(() => state.GetVariable("x").Value = "str");
Assert.Throws<InvalidOperationException>(() => state.GetVariable("y").Value = "str");
Assert.Throws<InvalidOperationException>(() => state.GetVariable("z").Value = "str");
Assert.Throws<InvalidOperationException>(() => state.GetVariable("y").Value = 0);
Assert.Throws<InvalidOperationException>(() => state.GetVariable("z").Value = 0);
}
[Fact]
......
......@@ -113,21 +113,17 @@ Microsoft.CodeAnalysis.Scripting.ScriptRunner<T>
Microsoft.CodeAnalysis.Scripting.ScriptState
Microsoft.CodeAnalysis.Scripting.ScriptState.ContinueWithAsync(string code, Microsoft.CodeAnalysis.Scripting.ScriptOptions options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Scripting.ScriptState<object>>
Microsoft.CodeAnalysis.Scripting.ScriptState.ContinueWithAsync<TResult>(string code, Microsoft.CodeAnalysis.Scripting.ScriptOptions options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Scripting.ScriptState<TResult>>
Microsoft.CodeAnalysis.Scripting.ScriptState.GetVariable(string name) -> Microsoft.CodeAnalysis.Scripting.ScriptVariable
Microsoft.CodeAnalysis.Scripting.ScriptState.ReturnValue.get -> object
Microsoft.CodeAnalysis.Scripting.ScriptState.Script.get -> Microsoft.CodeAnalysis.Scripting.Script
Microsoft.CodeAnalysis.Scripting.ScriptState.Variables.get -> Microsoft.CodeAnalysis.Scripting.ScriptVariables
Microsoft.CodeAnalysis.Scripting.ScriptState.Variables.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Scripting.ScriptVariable>
Microsoft.CodeAnalysis.Scripting.ScriptState<T>
Microsoft.CodeAnalysis.Scripting.ScriptState<T>.ReturnValue.get -> T
Microsoft.CodeAnalysis.Scripting.ScriptVariable
Microsoft.CodeAnalysis.Scripting.ScriptVariable.Name.get -> string
Microsoft.CodeAnalysis.Scripting.ScriptVariable.Type.get -> System.Type
Microsoft.CodeAnalysis.Scripting.ScriptVariable.Value.get -> object
Microsoft.CodeAnalysis.Scripting.ScriptVariables
Microsoft.CodeAnalysis.Scripting.ScriptVariables.ContainsVariable(string name) -> bool
Microsoft.CodeAnalysis.Scripting.ScriptVariables.Count.get -> int
Microsoft.CodeAnalysis.Scripting.ScriptVariables.GetEnumerator() -> System.Collections.Generic.IEnumerator<Microsoft.CodeAnalysis.Scripting.ScriptVariable>
Microsoft.CodeAnalysis.Scripting.ScriptVariables.Names.get -> System.Collections.Generic.IEnumerable<string>
Microsoft.CodeAnalysis.Scripting.ScriptVariables.this[string name].get -> Microsoft.CodeAnalysis.Scripting.ScriptVariable
Microsoft.CodeAnalysis.Scripting.ScriptVariable.Value.set -> void
abstract Microsoft.CodeAnalysis.Scripting.ObjectFormatter.FormatArrayTypeName(System.Type arrayType, System.Array arrayOpt, Microsoft.CodeAnalysis.Scripting.ObjectFormattingOptions options) -> string
abstract Microsoft.CodeAnalysis.Scripting.ObjectFormatter.FormatGeneratedTypeName(System.Type type) -> string
abstract Microsoft.CodeAnalysis.Scripting.ObjectFormatter.FormatLiteral(System.DateTime value) -> string
......
// 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.Text;
using System.Threading;
using Microsoft.CodeAnalysis.Text;
......@@ -10,6 +11,7 @@ internal abstract class ScriptCompiler
{
public abstract Compilation CreateSubmission(Script script);
public abstract DiagnosticFormatter DiagnosticFormatter { get; }
public abstract StringComparer IdentifierComparer { get; }
public abstract SyntaxTree ParseSubmission(SourceText text, CancellationToken cancellationToken);
public abstract bool IsCompleteSubmission(SyntaxTree tree);
......
......@@ -51,8 +51,13 @@ public ScriptExecutionState FreezeAndClone()
}
}
public int Count => _count;
public object this[int index] => _submissionStates[index];
public int SubmissionStateCount => _count;
public object GetSubmissionState(int index)
{
Debug.Assert(index >= 0 && index < _count);
return _submissionStates[index];
}
internal async Task<TResult> RunSubmissionsAsync<TResult>(
ImmutableArray<Func<object[], Task>> precedingExecutors,
......
// 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.Immutable;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Reflection;
using System.Collections.Generic;
namespace Microsoft.CodeAnalysis.Scripting
{
......@@ -18,6 +22,9 @@ public abstract class ScriptState
internal ScriptExecutionState ExecutionState { get; }
private ImmutableArray<ScriptVariable> _lazyVariables;
private IReadOnlyDictionary<string, int> _lazyVariableMap;
internal ScriptState(ScriptExecutionState executionState, Script script)
{
Debug.Assert(executionState != null);
......@@ -33,24 +40,83 @@ internal ScriptState(ScriptExecutionState executionState, Script script)
public object ReturnValue => GetReturnValue();
internal abstract object GetReturnValue();
private ScriptVariables _lazyVariables;
/// <summary>
/// The global variables accessible to or declared by the script.
/// Returns variables defined by the scripts in the declaration order.
/// </summary>
public ScriptVariables Variables
public ImmutableArray<ScriptVariable> Variables
{
get
{
if (_lazyVariables == null)
{
Interlocked.CompareExchange(ref _lazyVariables, new ScriptVariables(ExecutionState), null);
ImmutableInterlocked.InterlockedInitialize(ref _lazyVariables, CreateVariables());
}
return _lazyVariables;
}
}
/// <summary>
/// Returns a script variable of the specified name.
/// </summary>
/// <remarks>
/// If multiple script variables are defined in the script (in distinct submissions) returns the last one.
/// Namve lookup is case sensitive in C# scripts and case insensitive in VB scripts.
/// </remarks>
/// <returns><see cref="ScriptVariable"/> or null, if no variable of the specified <paramref name="name"/> is defined in the script.</returns>
/// <exception cref="ArgumentNullException"><paramref name="name"/> is null.</exception>
public ScriptVariable GetVariable(string name)
{
if (name == null)
{
throw new ArgumentNullException(nameof(name));
}
int index;
return GetVariableMap().TryGetValue(name, out index) ? Variables[index] : null;
}
private ImmutableArray<ScriptVariable> CreateVariables()
{
var result = ImmutableArray.CreateBuilder<ScriptVariable>();
var executionState = ExecutionState;
// Don't include the globals object (slot #0)
for (int i = 1; i < executionState.SubmissionStateCount; i++)
{
var state = executionState.GetSubmissionState(i);
Debug.Assert(state != null);
foreach (var field in state.GetType().GetTypeInfo().DeclaredFields)
{
// TODO: synthesized fields of submissions shouldn't be public
if (field.IsPublic && field.Name.Length > 0 && char.IsLetterOrDigit(field.Name[0]))
{
result.Add(new ScriptVariable(state, field));
}
}
}
return result.ToImmutable();
}
private IReadOnlyDictionary<string, int> GetVariableMap()
{
if (_lazyVariableMap == null)
{
var map = new Dictionary<string, int>(Script.Compiler.IdentifierComparer);
for (int i = 0; i < Variables.Length; i++)
{
map[Variables[i].Name] = i;
}
_lazyVariableMap = map;
}
return _lazyVariableMap;
}
public Task<ScriptState<object>> ContinueWithAsync(string code, ScriptOptions options = null, CancellationToken cancellationToken = default(CancellationToken))
{
return ContinueWithAsync<object>(code, options, cancellationToken);
......
......@@ -10,62 +10,58 @@ namespace Microsoft.CodeAnalysis.Scripting
/// A variable declared by the script.
/// </summary>
[DebuggerDisplay("{GetDebuggerDisplay(), nq}")]
public class ScriptVariable
public sealed class ScriptVariable
{
private readonly object _instance;
private readonly MemberInfo _member;
private readonly FieldInfo _field;
internal ScriptVariable(object instance, MemberInfo member)
internal ScriptVariable(object instance, FieldInfo field)
{
Debug.Assert(instance != null);
Debug.Assert(field != null);
_instance = instance;
_member = member;
_field = field;
}
/// <summary>
/// The name of the variable.
/// </summary>
public string Name
{
get { return _member.Name; }
}
public string Name => _field.Name;
/// <summary>
/// The type of the variable.
/// </summary>
public Type Type
{
get
{
var field = _member as FieldInfo;
if (field != null)
{
return field.FieldType;
}
return ((PropertyInfo)_member).PropertyType;
}
}
public Type Type => _field.FieldType;
/// <summary>
/// The value of the variable after running the script.
/// </summary>
/// <exception cref="InvalidOperationException">Variable is read-only or a constant.</exception>
/// <exception cref="ArgumentException">The type of the specified <paramref name="value"/> isn't assignable to the type of the variable.</exception>
public object Value
{
get
{
var field = _member as FieldInfo;
if (field != null)
return _field.GetValue(_instance);
}
set
{
if (_field.IsInitOnly)
{
return field.GetValue(_instance);
throw new InvalidOperationException(ScriptingResources.CannotSetReadOnlyVariable);
}
return ((PropertyInfo)_member).GetValue(_instance);
if (_field.IsLiteral)
{
throw new InvalidOperationException(ScriptingResources.CannotSetConstantVariable);
}
_field.SetValue(_instance, value);
}
}
private string GetDebuggerDisplay()
{
return string.Format("{0}: {1}", this.Name, this.Value?.ToString() ?? "<null>");
}
private string GetDebuggerDisplay() => $"{Name}: {Value ?? "<null>"}";
}
}
\ No newline at end of file
// 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;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Microsoft.CodeAnalysis.Scripting
{
/// <summary>
/// A collection that holds the final state of all global variables used by the script.
/// </summary>
public class ScriptVariables : IEnumerable<ScriptVariable>, IEnumerable
{
private readonly Dictionary<string, ScriptVariable> _map;
internal ScriptVariables(ScriptExecutionState executionState)
{
_map = CreateVariableMap(executionState);
}
public int Count
{
get { return _map.Count; }
}
/// <summary>
/// Returns the global variable with the specified name.
/// </summary>
public ScriptVariable this[string name]
{
get
{
ScriptVariable global;
if (_map.TryGetValue(name, out global))
{
return global;
}
else
{
return null;
}
}
}
/// <summary>
/// Determines if a global variable with the specified name exists.
/// </summary>
public bool ContainsVariable(string name)
{
return _map.ContainsKey(name);
}
/// <summary>
/// A list the global variable names.
/// </summary>
public IEnumerable<String> Names
{
get { return _map.Keys; }
}
/// <summary>
/// Gets an enumerator over all the variables.
/// </summary>
public IEnumerator<ScriptVariable> GetEnumerator()
{
return _map.Values.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
private static Dictionary<string, ScriptVariable> CreateVariableMap(ScriptExecutionState executionState)
{
var map = new Dictionary<string, ScriptVariable>();
for (int i = 0; i < executionState.Count; i++)
{
var state = executionState[i];
if (state != null)
{
AddVariables(map, state);
}
}
return map;
}
private static void AddVariables(Dictionary<string, ScriptVariable> map, object instance)
{
var typeInfo = instance.GetType().GetTypeInfo();
foreach (var field in typeInfo.DeclaredFields)
{
if (field.IsPublic)
{
AddVariable(map, instance, field);
}
}
foreach (var property in typeInfo.DeclaredProperties)
{
if (property.GetMethod.IsPublic)
{
AddVariable(map, instance, property);
}
}
}
private static void AddVariable(Dictionary<string, ScriptVariable> map, object instance, MemberInfo member)
{
if (member.Name.Length > 0 && char.IsLetterOrDigit(member.Name[0]) && !map.ContainsKey(member.Name))
{
map.Add(member.Name, new ScriptVariable(instance, member));
}
}
}
}
\ No newline at end of file
......@@ -70,6 +70,11 @@
<Compile Include="AssemblyLoader\ShadowCopy.cs" />
<Compile Include="Resolvers\NuGetPackageResolver.cs" />
<Compile Include="ScriptCompiler.cs" />
<Compile Include="ScriptingResources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>ScriptingResources.resx</DependentUpon>
</Compile>
<Compile Include="ScriptRunner.cs" />
<Compile Include="ObjectFormatter.cs" />
<Compile Include="ObjectFormatter.Formatter.cs" />
......@@ -80,12 +85,6 @@
<Compile Include="MemberDisplayFormat.cs" />
<Compile Include="ObjectFormattingOptions.cs" />
<Compile Include="ScriptExecutionState.cs" />
<Compile Include="ScriptingResources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>ScriptingResources.resx</DependentUpon>
</Compile>
<Compile Include="ScriptVariables.cs" />
<Compile Include="ScriptOptions.cs" />
<Compile Include="ScriptState.cs" />
<Compile Include="ScriptVariable.cs" />
......@@ -108,8 +107,8 @@
<ItemGroup>
<EmbeddedResource Include="ScriptingResources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>ScriptingResources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
<LastGenOutput>ScriptingResources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
......
......@@ -79,6 +79,24 @@ internal class ScriptingResources {
}
}
/// <summary>
/// Looks up a localized string similar to Cannot set a constant variable.
/// </summary>
internal static string CannotSetConstantVariable {
get {
return ResourceManager.GetString("CannotSetConstantVariable", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Cannot set a read-only variable.
/// </summary>
internal static string CannotSetReadOnlyVariable {
get {
return ResourceManager.GetString("CannotSetReadOnlyVariable", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Can&apos;t assign &apos;{0}&apos; to &apos;{1}&apos;..
/// </summary>
......
......@@ -140,4 +140,10 @@
<data name="AtFileLine" xml:space="preserve">
<value> at {0} : {1}</value>
</data>
<data name="CannotSetReadOnlyVariable" xml:space="preserve">
<value>Cannot set a read-only variable</value>
</data>
<data name="CannotSetConstantVariable" xml:space="preserve">
<value>Cannot set a constant variable</value>
</data>
</root>
\ No newline at end of file
......@@ -25,6 +25,12 @@ Namespace Microsoft.CodeAnalysis.Scripting.VisualBasic
End Get
End Property
Public Overrides ReadOnly Property IdentifierComparer As StringComparer
Get
Return CaseInsensitiveComparison.Comparer
End Get
End Property
Public Overrides Function IsCompleteSubmission(tree As SyntaxTree) As Boolean
' TODO: https://github.com/dotnet/roslyn/issues/5235
Return True
......
......@@ -89,6 +89,9 @@
<Compile Include="..\..\..\Compilers\Helpers\AbstractAnalyzerAssemblyLoader.cs">
<Link>AbstractAnalyzerAssemblyLoader.cs</Link>
</Compile>
<Compile Include="..\..\..\Compilers\Helpers\AnalyzerAssemblyLoadUtils.cs">
<Link>AnalyzerAssemblyLoadUtils.cs</Link>
</Compile>
<Compile Include="..\..\..\Compilers\Helpers\SimpleAnalyzerAssemblyLoader.cs">
<Link>SimpleAnalyzerAssemblyLoader.cs</Link>
</Compile>
......@@ -163,4 +166,4 @@
<Import Project="..\..\..\..\build\Targets\VSL.Imports.targets" />
<Import Project="..\..\..\..\build\Targets\Roslyn.Toolsets.Xunit.targets" />
</ImportGroup>
</Project>
</Project>
\ No newline at end of file
......@@ -25,7 +25,14 @@ public static class TokenUtilities
for (var i = 0; i < Math.Min(expectedTokens.Count, actualTokens.Count); i++)
{
Assert.Equal(expectedTokens[i].ToString(), actualTokens[i].ToString());
var expectedToken = expectedTokens[i].ToString();
var actualToken = actualTokens[i].ToString();
if (!String.Equals(expectedToken, actualToken))
{
var prev = (i - 1 > -1) ? actualTokens[i - 1].ToString() : "^";
var next = (i + 1 < actualTokens.Count) ? actualTokens[i + 1].ToString() : "$";
AssertEx.Fail($"Unexpected token at index {i} near \"{prev} {actualToken} {next}\". Expected '{expectedToken}', Actual '{actualToken}'");
}
}
if (expectedTokens.Count != actualTokens.Count)
......
......@@ -33,7 +33,6 @@
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
......@@ -48,4 +47,4 @@
<ImportGroup Label="Targets">
<Import Project="..\..\..\..\..\..\build\Targets\VSL.Imports.targets" />
</ImportGroup>
</Project>
</Project>
\ No newline at end of file
......@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
......@@ -365,6 +366,13 @@ public virtual bool TryHandleReturn()
public virtual bool TryInsertExpansion(int startPositionInSubjectBuffer, int endPositionInSubjectBuffer)
{
var textViewModel = TextView.TextViewModel;
if (textViewModel == null)
{
Debug.Assert(TextView.IsClosed);
return false;
}
int startLine = 0;
int startIndex = 0;
int endLine = 0;
......@@ -377,13 +385,13 @@ public virtual bool TryInsertExpansion(int startPositionInSubjectBuffer, int end
SnapshotSpan dataBufferSpan;
if (!TryGetSpanOnHigherBuffer(
SubjectBuffer.CurrentSnapshot.GetSpan(startPositionInSubjectBuffer, endPositionInSubjectBuffer - startPositionInSubjectBuffer),
TextView.TextViewModel.DataBuffer,
textViewModel.DataBuffer,
out dataBufferSpan))
{
return false;
}
var buffer = EditorAdaptersFactoryService.GetBufferAdapter(TextView.TextViewModel.DataBuffer);
var buffer = EditorAdaptersFactoryService.GetBufferAdapter(textViewModel.DataBuffer);
var expansion = buffer as IVsExpansion;
if (buffer == null || expansion == null)
{
......@@ -446,6 +454,13 @@ public int OnBeforeInsertion(IVsExpansionSession pSession)
public int OnItemChosen(string pszTitle, string pszPath)
{
var textViewModel = TextView.TextViewModel;
if (textViewModel == null)
{
Debug.Assert(TextView.IsClosed);
return VSConstants.E_FAIL;
}
var hr = VSConstants.S_OK;
try
......@@ -456,7 +471,7 @@ public int OnItemChosen(string pszTitle, string pszPath)
textSpan.iEndLine = textSpan.iStartLine;
textSpan.iEndIndex = textSpan.iStartIndex;
IVsExpansion expansion = EditorAdaptersFactoryService.GetBufferAdapter(TextView.TextViewModel.DataBuffer) as IVsExpansion;
IVsExpansion expansion = EditorAdaptersFactoryService.GetBufferAdapter(textViewModel.DataBuffer) as IVsExpansion;
earlyEndExpansionHappened = false;
hr = expansion.InsertNamedExpansion(pszTitle, pszPath, textSpan, this, LanguageServiceGuid, fShowDisambiguationUI: 0, pSession: out ExpansionSession);
......
......@@ -53,12 +53,20 @@ public override int GetDataTipText(TextSpan[] pSpan, out string pbstrText)
return VSConstants.E_INVALIDARG;
}
var textViewModel = WpfTextView.TextViewModel;
if (textViewModel == null)
{
Debug.Assert(WpfTextView.IsClosed);
pbstrText = null;
return VSConstants.E_FAIL;
}
// We need to map the TextSpan from the DataBuffer to our subject buffer. We'll
// only consider spans whose length matches our input span (which we expect to
// always be zero). This is to address the case where the position is on a seam
// and maps to multiple source spans.
// If there is not exactly one matching span, just return.
var span = WpfTextView.TextViewModel.DataBuffer.CurrentSnapshot.GetSpan(pSpan[0]);
var span = textViewModel.DataBuffer.CurrentSnapshot.GetSpan(pSpan[0]);
var spanLength = span.Length;
Debug.Assert(spanLength == 0, $"Expected zero length span (got '{spanLength}'.");
var subjectSpan = WpfTextView.BufferGraph.MapDownToBuffer(span, SpanTrackingMode.EdgeInclusive, _subjectBuffer)
......@@ -83,7 +91,7 @@ public override int GetDataTipText(TextSpan[] pSpan, out string pbstrText)
// take the span that intersects with the input span, since that's probably
// the one we care about.
// If there are no such spans, just return.
var surfaceSpan = WpfTextView.BufferGraph.MapUpToBuffer(subjectSpan, SpanTrackingMode.EdgeInclusive, WpfTextView.TextViewModel.DataBuffer)
var surfaceSpan = WpfTextView.BufferGraph.MapUpToBuffer(subjectSpan, SpanTrackingMode.EdgeInclusive, textViewModel.DataBuffer)
.SingleOrDefault(x => x.IntersectsWith(span));
if (surfaceSpan == default(SnapshotSpan))
......
......@@ -43,27 +43,22 @@ public static ExpressionSyntax WalkDownParentheses(this ExpressionSyntax express
public static ExpressionSyntax Parenthesize(this ExpressionSyntax expression, bool includeElasticTrivia = true)
{
var leadingTrivia = expression.GetLeadingTrivia();
var trailingTrivia = expression.GetTrailingTrivia();
expression = expression.WithoutLeadingTrivia()
.WithoutTrailingTrivia();
if (includeElasticTrivia)
{
return SyntaxFactory.ParenthesizedExpression(expression)
.WithLeadingTrivia(leadingTrivia)
.WithTrailingTrivia(trailingTrivia)
.WithAdditionalAnnotations(Simplifier.Annotation);
return SyntaxFactory.ParenthesizedExpression(expression.WithoutTrivia())
.WithTriviaFrom(expression)
.WithAdditionalAnnotations(Simplifier.Annotation);
}
else
{
return SyntaxFactory.ParenthesizedExpression(
return SyntaxFactory.ParenthesizedExpression
(
SyntaxFactory.Token(SyntaxTriviaList.Empty, SyntaxKind.OpenParenToken, SyntaxTriviaList.Empty),
expression,
SyntaxFactory.Token(SyntaxTriviaList.Empty, SyntaxKind.CloseParenToken, SyntaxTriviaList.Empty))
.WithLeadingTrivia(leadingTrivia)
.WithTrailingTrivia(trailingTrivia)
.WithAdditionalAnnotations(Simplifier.Annotation);
expression.WithoutTrivia(),
SyntaxFactory.Token(SyntaxTriviaList.Empty, SyntaxKind.CloseParenToken, SyntaxTriviaList.Empty)
)
.WithTriviaFrom(expression)
.WithAdditionalAnnotations(Simplifier.Annotation);
}
}
......@@ -2338,7 +2333,7 @@ public static OperatorPrecedence GetOperatorPrecedence(this ExpressionSyntax exp
case SyntaxKind.UncheckedExpression:
case SyntaxKind.AnonymousMethodExpression:
// From C# spec, 7.3.1:
// Primary: x.y f(x) a[x] x++ x-- new typeof default checked unchecked delegate
// Primary: x.y x?.y x?[y] f(x) a[x] x++ x-- new typeof default checked unchecked delegate
return OperatorPrecedence.Primary;
......@@ -2349,8 +2344,9 @@ public static OperatorPrecedence GetOperatorPrecedence(this ExpressionSyntax exp
case SyntaxKind.PreIncrementExpression:
case SyntaxKind.PreDecrementExpression:
case SyntaxKind.CastExpression:
case SyntaxKind.AwaitExpression:
// From C# spec, 7.3.1:
// Unary: + - ! ~ ++x --x (T)x
// Unary: + - ! ~ ++x --x (T)x await Task
return OperatorPrecedence.Unary;
......
......@@ -58,6 +58,9 @@
<Compile Include="..\..\..\Compilers\Helpers\AbstractAnalyzerAssemblyLoader.cs">
<Link>InternalUtilities\AbstractAnalyzerAssemblyLoader.cs</Link>
</Compile>
<Compile Include="..\..\..\Compilers\Helpers\AnalyzerAssemblyLoadUtils.cs">
<Link>AnalyzerAssemblyLoadUtils.cs</Link>
</Compile>
<Compile Include="..\..\..\Compilers\Helpers\GlobalAssemblyCacheHelpers\FusionAssemblyIdentity.cs">
<Link>InternalUtilities\FusionAssemblyIdentity.cs</Link>
</Compile>
......@@ -167,4 +170,4 @@
<ImportGroup Label="Targets">
<Import Project="..\..\..\..\build\Targets\VSL.Imports.targets" />
</ImportGroup>
</Project>
\ No newline at end of file
</Project>
......@@ -52,15 +52,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions
<Extension()>
Public Function Parenthesize(expression As ExpressionSyntax) As ParenthesizedExpressionSyntax
Dim leadingTrivia = expression.GetLeadingTrivia()
Dim trailingTrivia = expression.GetTrailingTrivia()
Dim strippedExpression = expression.WithoutLeadingTrivia().WithoutTrailingTrivia()
Return SyntaxFactory.ParenthesizedExpression(strippedExpression) _
.WithLeadingTrivia(leadingTrivia) _
.WithTrailingTrivia(trailingTrivia) _
.WithAdditionalAnnotations(Simplifier.Annotation)
Return SyntaxFactory.ParenthesizedExpression(expression.WithoutTrivia()) _
.WithTriviaFrom(expression) _
.WithAdditionalAnnotations(Simplifier.Annotation)
End Function
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册