提交 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 ...@@ -848,7 +848,7 @@ public override ImmutableArray<MetadataReference> DirectiveReferences
} }
} }
internal override IDictionary<string, MetadataReference> ReferenceDirectiveMap internal override IDictionary<ValueTuple<string, string>, MetadataReference> ReferenceDirectiveMap
{ {
get get
{ {
...@@ -911,10 +911,11 @@ internal override IEnumerable<ReferenceDirective> ReferenceDirectives ...@@ -911,10 +911,11 @@ internal override IEnumerable<ReferenceDirective> ReferenceDirectives
/// Returns a metadata reference that a given #r resolves to. /// Returns a metadata reference that a given #r resolves to.
/// </summary> /// </summary>
/// <param name="directive">#r directive.</param> /// <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) 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> /// <summary>
......
...@@ -313,7 +313,7 @@ private bool CreateAndSetSourceAssemblyFullBind(CSharpCompilation compilation) ...@@ -313,7 +313,7 @@ private bool CreateAndSetSourceAssemblyFullBind(CSharpCompilation compilation)
try try
{ {
IDictionary<string, MetadataReference> boundReferenceDirectiveMap; IDictionary<ValueTuple<string, string>, MetadataReference> boundReferenceDirectiveMap;
ImmutableArray<MetadataReference> boundReferenceDirectives; ImmutableArray<MetadataReference> boundReferenceDirectives;
ImmutableArray<AssemblyData> referencedAssemblies; ImmutableArray<AssemblyData> referencedAssemblies;
ImmutableArray<PEModule> modules; // To make sure the modules are not collected ahead of time. ImmutableArray<PEModule> modules; // To make sure the modules are not collected ahead of time.
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Emit; using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities;
...@@ -326,6 +327,59 @@ public void ReferenceAPITest() ...@@ -326,6 +327,59 @@ public void ReferenceAPITest()
Assert.Equal(0, compCollection.ExternalReferences.Length); 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")] [Fact, WorkItem(530131, "DevDiv")]
public void MetadataReferenceWithInvalidAlias() public void MetadataReferenceWithInvalidAlias()
{ {
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities; using Roslyn.Test.Utilities;
...@@ -1345,6 +1346,40 @@ public void ResolvedReferencesCaching() ...@@ -1345,6 +1346,40 @@ public void ResolvedReferencesCaching()
var a2 = c2.SourceAssembly; 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] [Fact]
public void CyclesInReferences() public void CyclesInReferences()
{ {
......
...@@ -495,7 +495,7 @@ internal CommonReferenceManager GetBoundReferenceManager() ...@@ -495,7 +495,7 @@ internal CommonReferenceManager GetBoundReferenceManager()
/// <summary> /// <summary>
/// Maps values of #r references to resolved metadata references. /// Maps values of #r references to resolved metadata references.
/// </summary> /// </summary>
internal abstract IDictionary<string, MetadataReference> ReferenceDirectiveMap { get; } internal abstract IDictionary<ValueTuple<string, string>, MetadataReference> ReferenceDirectiveMap { get; }
/// <summary> /// <summary>
/// All metadata references -- references passed to the compilation /// All metadata references -- references passed to the compilation
......
...@@ -192,7 +192,7 @@ public ReferencedAssemblyIdentity(AssemblyIdentity identity, MetadataReference r ...@@ -192,7 +192,7 @@ public ReferencedAssemblyIdentity(AssemblyIdentity identity, MetadataReference r
TCompilation compilation, TCompilation compilation,
[Out] Dictionary<string, List<ReferencedAssemblyIdentity>> assemblyReferencesBySimpleName, [Out] Dictionary<string, List<ReferencedAssemblyIdentity>> assemblyReferencesBySimpleName,
out ImmutableArray<MetadataReference> references, out ImmutableArray<MetadataReference> references,
out IDictionary<string, MetadataReference> boundReferenceDirectiveMap, out IDictionary<ValueTuple<string, string>, MetadataReference> boundReferenceDirectiveMap,
out ImmutableArray<MetadataReference> boundReferenceDirectives, out ImmutableArray<MetadataReference> boundReferenceDirectives,
out ImmutableArray<AssemblyData> assemblies, out ImmutableArray<AssemblyData> assemblies,
out ImmutableArray<PEModule> modules, out ImmutableArray<PEModule> modules,
...@@ -744,7 +744,7 @@ private static void AddModule(PEModule module, int referenceIndex, ResolvedRefer ...@@ -744,7 +744,7 @@ private static void AddModule(PEModule module, int referenceIndex, ResolvedRefer
TCompilation compilation, TCompilation compilation,
DiagnosticBag diagnostics, DiagnosticBag diagnostics,
out ImmutableArray<MetadataReference> references, out ImmutableArray<MetadataReference> references,
out IDictionary<string, MetadataReference> boundReferenceDirectives, out IDictionary<ValueTuple<string, string>, MetadataReference> boundReferenceDirectives,
out ImmutableArray<Location> referenceDirectiveLocations) out ImmutableArray<Location> referenceDirectiveLocations)
{ {
boundReferenceDirectives = null; boundReferenceDirectives = null;
...@@ -763,7 +763,7 @@ private static void AddModule(PEModule module, int referenceIndex, ResolvedRefer ...@@ -763,7 +763,7 @@ private static void AddModule(PEModule module, int referenceIndex, ResolvedRefer
} }
// we already successfully bound #r with the same value: // 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; continue;
} }
...@@ -777,13 +777,13 @@ private static void AddModule(PEModule module, int referenceIndex, ResolvedRefer ...@@ -777,13 +777,13 @@ private static void AddModule(PEModule module, int referenceIndex, ResolvedRefer
if (boundReferenceDirectives == null) if (boundReferenceDirectives == null)
{ {
boundReferenceDirectives = new Dictionary<string, MetadataReference>(); boundReferenceDirectives = new Dictionary<ValueTuple<string, string>, MetadataReference>();
referenceDirectiveLocationsBuilder = ArrayBuilder<Location>.GetInstance(); referenceDirectiveLocationsBuilder = ArrayBuilder<Location>.GetInstance();
} }
referencesBuilder.Add(boundReference); referencesBuilder.Add(boundReference);
referenceDirectiveLocationsBuilder.Add(referenceDirective.Location); 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: // 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 ...@@ -792,7 +792,7 @@ private static void AddModule(PEModule module, int referenceIndex, ResolvedRefer
if (boundReferenceDirectives == null) if (boundReferenceDirectives == null)
{ {
// no directive references resolved successfully: // no directive references resolved successfully:
boundReferenceDirectives = SpecializedCollections.EmptyDictionary<string, MetadataReference>(); boundReferenceDirectives = SpecializedCollections.EmptyDictionary<ValueTuple<string, string>, MetadataReference>();
} }
references = referencesBuilder.ToImmutable(); references = referencesBuilder.ToImmutable();
......
...@@ -94,10 +94,10 @@ internal partial class CommonReferenceManager<TCompilation, TAssemblySymbol> : C ...@@ -94,10 +94,10 @@ internal partial class CommonReferenceManager<TCompilation, TAssemblySymbol> : C
private Dictionary<MetadataReference, int> _lazyReferencedModuleIndexMap; private Dictionary<MetadataReference, int> _lazyReferencedModuleIndexMap;
/// <summary> /// <summary>
/// Maps reference string used in #r directive to a resolved metadata reference. /// Maps (containing syntax tree file name, reference string) of #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. /// 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> /// </summary>
private IDictionary<string, MetadataReference> _lazyReferenceDirectiveMap; private IDictionary<ValueTuple<string, string>, MetadataReference> _lazyReferenceDirectiveMap;
/// <summary> /// <summary>
/// Array of unique bound #r references. /// Array of unique bound #r references.
...@@ -210,7 +210,7 @@ internal bool HasCircularReference ...@@ -210,7 +210,7 @@ internal bool HasCircularReference
} }
} }
internal IDictionary<string, MetadataReference> ReferenceDirectiveMap internal IDictionary<ValueTuple<string, string>, MetadataReference> ReferenceDirectiveMap
{ {
get get
{ {
...@@ -345,7 +345,7 @@ internal bool IsBound ...@@ -345,7 +345,7 @@ internal bool IsBound
internal void InitializeNoLock( internal void InitializeNoLock(
Dictionary<MetadataReference, int> referencedAssembliesMap, Dictionary<MetadataReference, int> referencedAssembliesMap,
Dictionary<MetadataReference, int> referencedModulesMap, Dictionary<MetadataReference, int> referencedModulesMap,
IDictionary<string, MetadataReference> boundReferenceDirectiveMap, IDictionary<ValueTuple<string, string>, MetadataReference> boundReferenceDirectiveMap,
ImmutableArray<MetadataReference> boundReferenceDirectives, ImmutableArray<MetadataReference> boundReferenceDirectives,
bool containsCircularReferences, bool containsCircularReferences,
ImmutableArray<Diagnostic> diagnostics, ImmutableArray<Diagnostic> diagnostics,
......
...@@ -1184,7 +1184,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -1184,7 +1184,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Get End Get
End Property 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 Get
Return GetBoundReferenceManager().ReferenceDirectiveMap Return GetBoundReferenceManager().ReferenceDirectiveMap
End Get End Get
......
...@@ -262,7 +262,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -262,7 +262,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Dim assemblyReferencesBySimpleName = PooledDictionary(Of String, List(Of ReferencedAssemblyIdentity)).GetInstance() Dim assemblyReferencesBySimpleName = PooledDictionary(Of String, List(Of ReferencedAssemblyIdentity)).GetInstance()
Try 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 boundReferenceDirectives As ImmutableArray(Of MetadataReference) = Nothing
Dim referencedAssemblies As ImmutableArray(Of AssemblyData) = 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. 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.
先完成此消息的编辑!
想要评论请 注册