提交 feeeb7e4 编写于 作者: T Tomas Matousek

Use script file path along with #r directive string in the directive reference map

上级 3ae534a8
......@@ -848,7 +848,7 @@ public override ImmutableArray<MetadataReference> DirectiveReferences
}
}
internal override IDictionary<string, MetadataReference> ReferenceDirectiveMap
internal override IDictionary<ValueTuple<string, string>, MetadataReference> ReferenceDirectiveMap
{
get
{
......@@ -911,10 +911,11 @@ internal override IEnumerable<ReferenceDirective> ReferenceDirectives
/// Returns a metadata reference that a given #r resolves to.
/// </summary>
/// <param name="directive">#r directive.</param>
/// <returns>Metadata reference the specified directive resolves to.</returns>
/// <returns>Metadata reference the specified directive resolves to, or null if the <paramref name="directive"/> doesn't match any #r directive in the compilation.</returns>
public MetadataReference GetDirectiveReference(ReferenceDirectiveTriviaSyntax directive)
{
return ReferenceDirectiveMap[directive.File.ValueText];
MetadataReference reference;
return ReferenceDirectiveMap.TryGetValue(ValueTuple.Create(directive.SyntaxTree.FilePath, directive.File.ValueText), out reference) ? reference : null;
}
/// <summary>
......
......@@ -313,7 +313,7 @@ private bool CreateAndSetSourceAssemblyFullBind(CSharpCompilation compilation)
try
{
IDictionary<string, MetadataReference> boundReferenceDirectiveMap;
IDictionary<ValueTuple<string, string>, MetadataReference> boundReferenceDirectiveMap;
ImmutableArray<MetadataReference> boundReferenceDirectives;
ImmutableArray<AssemblyData> referencedAssemblies;
ImmutableArray<PEModule> modules; // To make sure the modules are not collected ahead of time.
......
......@@ -13,6 +13,7 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.Test.Utilities;
......@@ -326,6 +327,59 @@ public void ReferenceAPITest()
Assert.Equal(0, compCollection.ExternalReferences.Length);
}
[Fact]
public void ReferenceDirectiveTests()
{
var t1 = Parse(@"
#r ""a.dll""
#r ""a.dll""
", filename: "1.csx", options: TestOptions.Script);
var rd1 = t1.GetRoot().GetDirectives().Cast<ReferenceDirectiveTriviaSyntax>().ToArray();
Assert.Equal(2, rd1.Length);
var t2 = Parse(@"
#r ""a.dll""
#r ""b.dll""
", options: TestOptions.Script);
var rd2 = t2.GetRoot().GetDirectives().Cast<ReferenceDirectiveTriviaSyntax>().ToArray();
Assert.Equal(2, rd2.Length);
var t3 = Parse(@"
#r ""a.dll""
", filename: "1.csx", options: TestOptions.Script);
var rd3 = t3.GetRoot().GetDirectives().Cast<ReferenceDirectiveTriviaSyntax>().ToArray();
Assert.Equal(1, rd3.Length);
var t4 = Parse(@"
#r ""a.dll""
", filename: "4.csx", options: TestOptions.Script);
var rd4 = t4.GetRoot().GetDirectives().Cast<ReferenceDirectiveTriviaSyntax>().ToArray();
Assert.Equal(1, rd4.Length);
var c = CreateCompilationWithMscorlib45(new[] { t1, t2 }, options: TestOptions.ReleaseDll.WithMetadataReferenceResolver(
new TestMetadataReferenceResolver(files: new Dictionary<string, PortableExecutableReference>()
{
{ @"a.dll", TestReferences.NetFx.v4_0_30319.Microsoft_CSharp },
{ @"b.dll", TestReferences.NetFx.v4_0_30319.Microsoft_VisualBasic },
})));
c.VerifyDiagnostics();
// same containing script file name and directive string
Assert.Same(TestReferences.NetFx.v4_0_30319.Microsoft_CSharp, c.GetDirectiveReference(rd1[0]));
Assert.Same(TestReferences.NetFx.v4_0_30319.Microsoft_CSharp, c.GetDirectiveReference(rd1[1]));
Assert.Same(TestReferences.NetFx.v4_0_30319.Microsoft_CSharp, c.GetDirectiveReference(rd2[0]));
Assert.Same(TestReferences.NetFx.v4_0_30319.Microsoft_VisualBasic, c.GetDirectiveReference(rd2[1]));
Assert.Same(TestReferences.NetFx.v4_0_30319.Microsoft_CSharp, c.GetDirectiveReference(rd3[0]));
// different script name or directive string:
Assert.Null(c.GetDirectiveReference(rd4[0]));
}
[Fact, WorkItem(530131, "DevDiv")]
public void MetadataReferenceWithInvalidAlias()
{
......
......@@ -7,6 +7,7 @@
using System.IO;
using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
......@@ -1345,6 +1346,40 @@ public void ResolvedReferencesCaching()
var a2 = c2.SourceAssembly;
}
[Fact]
public void ReferenceResolution_RelativePaths()
{
var t1 = Parse(@"
#r ""lib.dll""
", filename: @"C:\A\a.csx", options: TestOptions.Script);
var rd1 = (ReferenceDirectiveTriviaSyntax)t1.GetRoot().GetDirectives().Single();
var t2 = Parse(@"
#r ""lib.dll""
", filename: @"C:\B\b.csx", options: TestOptions.Script);
var rd2 = (ReferenceDirectiveTriviaSyntax)t2.GetRoot().GetDirectives().Single();
var c = CreateCompilationWithMscorlib45(new[] { t1, t2 }, options: TestOptions.ReleaseDll.WithMetadataReferenceResolver(
new TestMetadataReferenceResolver(
pathResolver: new VirtualizedRelativePathResolver(new[]
{
@"C:\A\lib.dll",
@"C:\B\lib.dll"
}),
files: new Dictionary<string, PortableExecutableReference>()
{
{ @"C:\A\lib.dll", TestReferences.NetFx.v4_0_30319.Microsoft_CSharp },
{ @"C:\B\lib.dll", TestReferences.NetFx.v4_0_30319.Microsoft_VisualBasic },
})));
c.VerifyDiagnostics();
Assert.Same(TestReferences.NetFx.v4_0_30319.Microsoft_CSharp, c.GetDirectiveReference(rd1));
Assert.Same(TestReferences.NetFx.v4_0_30319.Microsoft_VisualBasic, c.GetDirectiveReference(rd2));
}
[Fact]
public void CyclesInReferences()
{
......
......@@ -495,7 +495,7 @@ internal CommonReferenceManager GetBoundReferenceManager()
/// <summary>
/// Maps values of #r references to resolved metadata references.
/// </summary>
internal abstract IDictionary<string, MetadataReference> ReferenceDirectiveMap { get; }
internal abstract IDictionary<ValueTuple<string, string>, MetadataReference> ReferenceDirectiveMap { get; }
/// <summary>
/// All metadata references -- references passed to the compilation
......
......@@ -192,7 +192,7 @@ public ReferencedAssemblyIdentity(AssemblyIdentity identity, MetadataReference r
TCompilation compilation,
[Out] Dictionary<string, List<ReferencedAssemblyIdentity>> assemblyReferencesBySimpleName,
out ImmutableArray<MetadataReference> references,
out IDictionary<string, MetadataReference> boundReferenceDirectiveMap,
out IDictionary<ValueTuple<string, string>, MetadataReference> boundReferenceDirectiveMap,
out ImmutableArray<MetadataReference> boundReferenceDirectives,
out ImmutableArray<AssemblyData> assemblies,
out ImmutableArray<PEModule> modules,
......@@ -744,7 +744,7 @@ private static void AddModule(PEModule module, int referenceIndex, ResolvedRefer
TCompilation compilation,
DiagnosticBag diagnostics,
out ImmutableArray<MetadataReference> references,
out IDictionary<string, MetadataReference> boundReferenceDirectives,
out IDictionary<ValueTuple<string, string>, MetadataReference> boundReferenceDirectives,
out ImmutableArray<Location> referenceDirectiveLocations)
{
boundReferenceDirectives = null;
......@@ -763,7 +763,7 @@ private static void AddModule(PEModule module, int referenceIndex, ResolvedRefer
}
// we already successfully bound #r with the same value:
if (boundReferenceDirectives != null && boundReferenceDirectives.ContainsKey(referenceDirective.File))
if (boundReferenceDirectives != null && boundReferenceDirectives.ContainsKey(ValueTuple.Create(referenceDirective.Location.SourceTree.FilePath, referenceDirective.File)))
{
continue;
}
......@@ -777,13 +777,13 @@ private static void AddModule(PEModule module, int referenceIndex, ResolvedRefer
if (boundReferenceDirectives == null)
{
boundReferenceDirectives = new Dictionary<string, MetadataReference>();
boundReferenceDirectives = new Dictionary<ValueTuple<string, string>, MetadataReference>();
referenceDirectiveLocationsBuilder = ArrayBuilder<Location>.GetInstance();
}
referencesBuilder.Add(boundReference);
referenceDirectiveLocationsBuilder.Add(referenceDirective.Location);
boundReferenceDirectives.Add(referenceDirective.File, boundReference);
boundReferenceDirectives.Add(ValueTuple.Create(referenceDirective.Location.SourceTree.FilePath, referenceDirective.File), boundReference);
}
// add external reference at the end, so that they are processed first:
......@@ -792,7 +792,7 @@ private static void AddModule(PEModule module, int referenceIndex, ResolvedRefer
if (boundReferenceDirectives == null)
{
// no directive references resolved successfully:
boundReferenceDirectives = SpecializedCollections.EmptyDictionary<string, MetadataReference>();
boundReferenceDirectives = SpecializedCollections.EmptyDictionary<ValueTuple<string, string>, MetadataReference>();
}
references = referencesBuilder.ToImmutable();
......
......@@ -94,10 +94,10 @@ internal partial class CommonReferenceManager<TCompilation, TAssemblySymbol> : C
private Dictionary<MetadataReference, int> _lazyReferencedModuleIndexMap;
/// <summary>
/// Maps reference string used in #r directive to a resolved metadata reference.
/// If multiple #r's use the same value as a reference the resolved metadata reference is the same as well.
/// Maps (containing syntax tree file name, reference string) of #r directive to a resolved metadata reference.
/// If multiple #r's in the same tree use the same value as a reference the resolved metadata reference is the same as well.
/// </summary>
private IDictionary<string, MetadataReference> _lazyReferenceDirectiveMap;
private IDictionary<ValueTuple<string, string>, MetadataReference> _lazyReferenceDirectiveMap;
/// <summary>
/// Array of unique bound #r references.
......@@ -210,7 +210,7 @@ internal bool HasCircularReference
}
}
internal IDictionary<string, MetadataReference> ReferenceDirectiveMap
internal IDictionary<ValueTuple<string, string>, MetadataReference> ReferenceDirectiveMap
{
get
{
......@@ -345,7 +345,7 @@ internal bool IsBound
internal void InitializeNoLock(
Dictionary<MetadataReference, int> referencedAssembliesMap,
Dictionary<MetadataReference, int> referencedModulesMap,
IDictionary<string, MetadataReference> boundReferenceDirectiveMap,
IDictionary<ValueTuple<string, string>, MetadataReference> boundReferenceDirectiveMap,
ImmutableArray<MetadataReference> boundReferenceDirectives,
bool containsCircularReferences,
ImmutableArray<Diagnostic> diagnostics,
......
......@@ -1184,7 +1184,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Get
End Property
Friend Overrides ReadOnly Property ReferenceDirectiveMap As IDictionary(Of String, MetadataReference)
Friend Overrides ReadOnly Property ReferenceDirectiveMap As IDictionary(Of ValueTuple(Of String, String), MetadataReference)
Get
Return GetBoundReferenceManager().ReferenceDirectiveMap
End Get
......
......@@ -262,7 +262,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Dim assemblyReferencesBySimpleName = PooledDictionary(Of String, List(Of ReferencedAssemblyIdentity)).GetInstance()
Try
Dim boundReferenceDirectiveMap As IDictionary(Of String, MetadataReference) = Nothing
Dim boundReferenceDirectiveMap As IDictionary(Of ValueTuple(Of String, String), MetadataReference) = Nothing
Dim boundReferenceDirectives As ImmutableArray(Of MetadataReference) = Nothing
Dim referencedAssemblies As ImmutableArray(Of AssemblyData) = Nothing
Dim modules As ImmutableArray(Of PEModule) = Nothing ' To make sure the modules are not collected ahead of time.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册