private static TimeSpan RunCustomAssemblyLoder() { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); try { using (var loader = new InteractiveAssemblyLoader()) { if (AssemblyIdentity.TryParseDisplayName("CSScriptConsole, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", out AssemblyIdentity cccassemblyid)) { loader.RegisterDependency(cccassemblyid, Path.Combine(AppContext.BaseDirectory, "CSScriptConsole.dll")); } var option = ScriptOptions.Default .WithFilePath(Path.Combine(scriptrootpath, "CustomizeAssemblyLoading", "main.csx")) .WithFileEncoding(Encoding.UTF8); String code = "#load \"main.csx\""; var script = CSharpScript.Create(code, options: option, assemblyLoader: loader); var c = script.Compile(); var state = script.RunAsync(null).Result; } } catch (Exception ex) { Console.WriteLine($"{ex.Message}{Environment.NewLine}{ex.StackTrace}"); } finally { stopwatch.Stop(); } return(stopwatch.Elapsed); }
/// <summary> /// Attempts to find and load an <see cref="Assembly"/> when the requesting <see cref="Assembly"/> /// is unknown. /// </summary> /// <remarks> /// In this case we simply look next to all the assemblies we have previously loaded for one with the /// correct name and a matching <see cref="AssemblyIdentity"/>. /// </remarks> private static Assembly ResolveForUnknownRequestor(string requestedAssemblyName) { lock (s_guard) { string requestedNameWithPolicyApplied = AppDomain.CurrentDomain.ApplyPolicy(requestedAssemblyName); Assembly assembly; if (s_assembliesFromNames.TryGetValue(requestedNameWithPolicyApplied, out assembly)) { // We've already loaded an assembly by this name; use that. return(assembly); } AssemblyIdentity requestedAssemblyIdentity; if (!AssemblyIdentity.TryParseDisplayName(requestedNameWithPolicyApplied, out requestedAssemblyIdentity)) { return(null); } foreach (string loadedAssemblyFullPath in s_assembliesFromFiles.Keys) { string directoryPath = Path.GetDirectoryName(loadedAssemblyFullPath); string candidateAssemblyFullPath = Path.Combine(directoryPath, requestedAssemblyIdentity.Name + ".dll"); AssemblyIdentity candidateAssemblyIdentity = TryGetAssemblyIdentity(candidateAssemblyFullPath); if (requestedAssemblyIdentity.Equals(candidateAssemblyIdentity)) { return(LoadCore(candidateAssemblyFullPath)); } } return(null); } }
internal Assembly ResolveAssembly(string assemblyDisplayName, Assembly requestingAssemblyOpt) { AssemblyIdentity identity; if (!AssemblyIdentity.TryParseDisplayName(assemblyDisplayName, out identity)) { return(null); } string loadDirectoryOpt; lock (_referencesLock) { LoadedAssembly loadedAssembly; if (requestingAssemblyOpt != null && _assembliesLoadedFromLocation.TryGetValue(requestingAssemblyOpt, out loadedAssembly)) { loadDirectoryOpt = Path.GetDirectoryName(loadedAssembly.OriginalPath); } else { loadDirectoryOpt = null; } } return(ResolveAssembly(identity, loadDirectoryOpt)); }
private async Task <string> GetAssemblyNameFromInternalsVisibleToAttributeAsync( Document document, SyntaxNode node, CancellationToken cancellationToken ) { var constructorArgument = GetConstructorArgumentOfInternalsVisibleToAttribute(node); if (constructorArgument == null) { return(string.Empty); } var semanticModel = await document .ReuseExistingSpeculativeModelAsync(constructorArgument, cancellationToken) .ConfigureAwait(false); var constantCandidate = semanticModel.GetConstantValue( constructorArgument, cancellationToken ); if (constantCandidate.HasValue && constantCandidate.Value is string argument) { if (AssemblyIdentity.TryParseDisplayName(argument, out var assemblyIdentity)) { return(assemblyIdentity.Name); } } return(string.Empty); }
private (Project project, ISymbol symbol) TryResolveSymbolInCurrentSolution( Workspace workspace, string symbolKey) { if (!this.Properties.TryGetValue(MetadataAssemblyIdentityDisplayName, out var identityDisplayName) || !AssemblyIdentity.TryParseDisplayName(identityDisplayName, out var identity)) { return(null, null); } var project = workspace.CurrentSolution .ProjectsWithReferenceToAssembly(identity) .FirstOrDefault(); if (project == null) { return(null, null); } var compilation = project.GetCompilationAsync(CancellationToken.None) .WaitAndGetResult(CancellationToken.None); var symbol = SymbolKey.Resolve(symbolKey, compilation).Symbol; return(project, symbol); }
private static async Task <ISet <AssemblyIdentity> > GetUniqueIdentitiesAsync( CodeFixContext context ) { var cancellationToken = context.CancellationToken; var compilation = await context.Document.Project .GetCompilationAsync(cancellationToken) .ConfigureAwait(false); var uniqueIdentities = new HashSet <AssemblyIdentity>(); foreach (var diagnostic in context.Diagnostics) { var assemblyIds = compilation.GetUnreferencedAssemblyIdentities(diagnostic); uniqueIdentities.AddRange(assemblyIds); var properties = diagnostic.Properties; if ( properties.TryGetValue( DiagnosticPropertyConstants.UnreferencedAssemblyIdentity, out var displayName ) && AssemblyIdentity.TryParseDisplayName(displayName, out var serializedIdentity) ) { uniqueIdentities.Add(serializedIdentity); } } uniqueIdentities.Remove(compilation.Assembly.Identity); return(uniqueIdentities); }
private void TestParseDisplayName( string displayName, AssemblyIdentity expected, AssemblyIdentityParts expectedParts, AssemblyIdentity expectedFusion ) { var fusion = FusionAssemblyIdentity.ToAssemblyIdentity( FusionAssemblyIdentity.ToAssemblyNameObject(displayName) ); Assert.Equal(expectedFusion, fusion); AssemblyIdentity id = null; AssemblyIdentityParts actualParts; bool success = AssemblyIdentity.TryParseDisplayName( displayName, out id, out actualParts ); Assert.Equal(expected, id); Assert.Equal(success, id != null); Assert.Equal(expectedParts, actualParts); }
private Assembly AssemblyResolve(object sender, ResolveEventArgs args) { AssemblyIdentity identity; if (!AssemblyIdentity.TryParseDisplayName(args.Name, out identity)) { return(null); } if (args.RequestingAssembly != null) { string originalDllPath = null, originalExePath = null; string originalPath = null; lock (ReferencesLock) { LoadedAssembly loadedAssembly; if (_loadedAssemblies.TryGetValue(args.RequestingAssembly, out loadedAssembly)) { originalPath = loadedAssembly.OriginalPath; string pathWithoutExtension = Path.Combine(Path.GetDirectoryName(originalPath), identity.Name); originalDllPath = pathWithoutExtension + ".dll"; originalExePath = pathWithoutExtension + ".exe"; Assembly assembly; if (_loadedAssembliesByPath.TryGetValue(originalDllPath, out assembly) || _loadedAssembliesByPath.TryGetValue(originalExePath, out assembly)) { return(assembly); } } } // if the referring assembly is already loaded by our loader, load from its directory: if (originalPath != null) { // Copy & load both .dll and .exe, this is not a common scenario we would need to optimize for. // Remember both loaded assemblies for the next time, even though their versions might not match the current request // they might match the next one and we don't want to load them again. Assembly dll = ShadowCopyAndLoadDependency(originalDllPath); Assembly exe = ShadowCopyAndLoadDependency(originalExePath); if (dll == null ^ exe == null) { return(dll ?? exe); } if (dll != null && exe != null) { // .dll and an .exe of the same name might have different versions, // one of which might match the requested version. // Prefer .dll if they are both the same. return(FindHighestVersionOrFirstMatchingIdentity(identity, new[] { dll, exe })); } } } return(GetOrLoadKnownAssembly(identity)); }
public static bool InternalsVisibleToProxyGenerator(this ISymbol typeSymbol) { return(typeSymbol.ContainingAssembly != null && typeSymbol.ContainingAssembly.GetAttributes() .Any(att => att.AttributeClass.ToString() == MetadataNames.InternalsVisibleToAttributeFullTypeName && att.ConstructorArguments.Any(arg => arg.Value != null && AssemblyIdentity.TryParseDisplayName(arg.Value.ToString(), out var identity) && identity.Name == MetadataNames.CastleDynamicProxyGenAssembly2Name))); }
public void ValidAnalyzerReference_Id() { AnalyzerFileReference reference = CreateAnalyzerFileReference(_testFixture.Alpha.Path); AssemblyIdentity.TryParseDisplayName("Alpha, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", out var expectedIdentity); Assert.Equal(expected: expectedIdentity, actual: reference.Id); }
public void AssemblyIdentity_EmptyName() { var identity = new AssemblyIdentity(noThrow: true, name: ""); var name = identity.GetDisplayName(); Assert.Equal(", Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", name); Assert.False(AssemblyIdentity.TryParseDisplayName(name, out _)); }
private void TestMatch( string displayName1, string displayName2, AssemblyIdentityComparer.ComparisonResult match, AssemblyIdentityComparer.ComparisonResult?fusionMatch = null, bool ignoreVersion = false, bool partial = false, bool unificationApplied = false, bool?fusionUnificationApplied = null, string policyPath = null) { if (fusionMatch == null) { fusionMatch = match; } using (var fusionPolicy = policyPath != null ? FusionAssemblyPortabilityPolicy.LoadFromFile(policyPath) : null) { var comparer = DesktopAssemblyIdentityComparer.Default; var policy = default(AssemblyPortabilityPolicy); if (policyPath != null) { using (var policyStream = new FileStream(policyPath, FileMode.Open, FileAccess.Read)) { policy = AssemblyPortabilityPolicy.LoadFromXml(policyStream); comparer = new DesktopAssemblyIdentityComparer(policy); } } bool fusionUnificationApplied1; var fusionResult1 = FusionAssemblyIdentityComparer.CompareAssemblyIdentity(displayName1, displayName2, ignoreVersion, policy: fusionPolicy, unificationApplied: out fusionUnificationApplied1); Assert.Equal(fusionMatch, fusionResult1); Assert.Equal(fusionUnificationApplied ?? unificationApplied, fusionUnificationApplied1); AssemblyIdentity id1, id2; AssemblyIdentityParts parts1, parts2; Assert.True(AssemblyIdentity.TryParseDisplayName(displayName1, out id1, out parts1)); Assert.Equal(partial, !AssemblyIdentity.IsFullName(parts1)); Assert.True(AssemblyIdentity.TryParseDisplayName(displayName2, out id2, out parts2)); Assert.True(AssemblyIdentity.IsFullName(parts2), "Expected full name"); bool unificationApplied1; var actual1 = comparer.Compare(null, displayName1, id2, out unificationApplied1, ignoreVersion); Assert.Equal(match, actual1); Assert.Equal(unificationApplied, unificationApplied1); if (!partial && id1 != null) { bool unificationApplied2; var actual2 = comparer.Compare(id1, null, id2, out unificationApplied2, ignoreVersion); Assert.Equal(match, actual2); Assert.Equal(unificationApplied, unificationApplied2); } } }
public static string DumpAssemblyData(IEnumerable <ModuleData> modules, out string dumpDirectory) { dumpDirectory = null; StringBuilder sb = new StringBuilder(); foreach (var module in modules) { if (module.InMemoryModule) { if (dumpDirectory == null) { dumpDirectory = Path.Combine(Path.GetTempPath(), "RoslynTestFailureDump", Guid.NewGuid().ToString()); Directory.CreateDirectory(dumpDirectory); } string fileName; if (module.Kind == OutputKind.NetModule) { fileName = module.FullName; } else { AssemblyIdentity identity; AssemblyIdentity.TryParseDisplayName(module.FullName, out identity); fileName = identity.Name; } string pePath = Path.Combine(dumpDirectory, fileName + module.Kind.GetDefaultExtension()); string pdbPath = (module.Pdb != null) ? pdbPath = Path.Combine(dumpDirectory, fileName + ".pdb") : null; try { module.Image.WriteToFile(pePath); if (pdbPath != null) { module.Pdb.WriteToFile(pdbPath); } } catch (IOException) { pePath = "<unable to write file>"; if (pdbPath != null) { pdbPath = "<unable to write file>"; } } sb.Append("PE(" + module.Kind + "): "); sb.AppendLine(pePath); if (pdbPath != null) { sb.Append("PDB: "); sb.AppendLine(pdbPath); } } } return(sb.ToString()); }
private static void AddAssemblyIdentity(List <AssemblyIdentity> list, string dllName) { if (!AssemblyIdentity.TryParseDisplayName(dllName, out var identity)) { return; } list.Add(identity); }
public void ValidAnalyzerReference_Id() { var directory = Temp.CreateDirectory(); var alphaDll = directory.CreateFile("Alpha.dll").WriteAllBytes(TestResources.AssemblyLoadTests.Alpha); AnalyzerFileReference reference = CreateAnalyzerFileReference(alphaDll.Path); AssemblyIdentity.TryParseDisplayName("Alpha, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", out var expectedIdentity); Assert.Equal(expected: expectedIdentity, actual: reference.Id); }
private Assembly AssemblyResolve(string assemblyDisplayName, Assembly requestingAssemblyOpt) { AssemblyIdentity identity; if (!AssemblyIdentity.TryParseDisplayName(assemblyDisplayName, out identity)) { return(null); } return(AssemblyResolve(identity, requestingAssemblyOpt)); }
public AssemblyIdentity ApplyBindingRedirects(AssemblyIdentity originalIdentity) { var redirectedAssemblyName = AppDomain.CurrentDomain.ApplyPolicy(originalIdentity.ToString()); if (AssemblyIdentity.TryParseDisplayName(redirectedAssemblyName, out var redirectedAssemblyIdentity)) { return(redirectedAssemblyIdentity); } return(originalIdentity); }
private void TestParseSimpleName(string displayName, string expected, string expectedFusion) { var fusionName = FusionAssemblyIdentity.ToAssemblyNameObject(displayName); var actual = (fusionName != null) ? FusionAssemblyIdentity.GetName(fusionName) : null; Assert.Equal(expectedFusion, actual); AssemblyIdentity id; actual = AssemblyIdentity.TryParseDisplayName(displayName, out id) ? id.Name : null; Assert.Equal(expected, actual); }
private void TestParseVersion(string value) { string displayName = "Foo, Version=" + value; var fusion = FusionAssemblyIdentity.ToAssemblyIdentity(FusionAssemblyIdentity.ToAssemblyNameObject(displayName)); AssemblyIdentity id = null; bool success = AssemblyIdentity.TryParseDisplayName(displayName, out id); Assert.Equal(fusion != null, success); if (success) { Assert.Equal(fusion.Version, id.Version); } }
public void TryParseDisplayName() { string V = "\\u" + ((int)'V').ToString("X4") + ";"; TestParseDisplayName(" \"fo'o\" , " + V + "ersion=1.0.0.0\t, \rCulture=zz-ZZ\n, PublicKeyToken=" + StrPublicKeyToken1, new AssemblyIdentity("fo'o", new Version(1, 0, 0, 0), "zz-ZZ", RoPublicKeyToken1, hasPublicKey: false, isRetargetable: false, contentType: AssemblyContentType.Default), NVCT); // invalid: AssemblyIdentity id; Assert.Throws <ArgumentNullException>(() => AssemblyIdentity.TryParseDisplayName(null, out id)); TestParseDisplayName("", null); TestParseDisplayName("fo=o, Culture=neutral, Version=1.0.0.0", null); TestParseDisplayName("foo, Culture=neutral, Version,1.0.0.0", null); // custom properties: TestParseDisplayName("foo, A=B", new AssemblyIdentity("foo"), N | AssemblyIdentityParts.Unknown); // we don't allow CT=WinRT + Retargetable, fusion does. Assert.False( AssemblyIdentity.TryParseDisplayName("foo, Version=1.0.0.0, Culture=en-US, Retargetable=Yes, ContentType=WindowsRuntime, PublicKeyToken=" + StrPublicKeyToken1, out id)); // order TestParseDisplayName("foo, Culture=neutral, Version=1.0.0.0", new AssemblyIdentity("foo", new Version(1, 0, 0, 0)), NVC); TestParseDisplayName("foo, Version=1.0.0.0, Culture=en-US, Retargetable=Yes, PublicKeyToken=" + StrPublicKeyToken1, new AssemblyIdentity("foo", new Version(1, 0, 0, 0), "en-US", RoPublicKeyToken1, hasPublicKey: false, isRetargetable: true), NVCT | AssemblyIdentityParts.Retargetability); TestParseDisplayName("foo, PublicKey=" + StrPublicKey1 + ", Version=1.0.0.1", new AssemblyIdentity("foo", new Version(1, 0, 0, 1), publicKeyOrToken: RoPublicKey1, hasPublicKey: true), NVK); TestParseDisplayName(@"Foo, Version=0.0.0.0, Culture="" \'\t\r\n\\\=\, "", PublicKeyToken=null", new AssemblyIdentity("Foo", cultureName: " '\t\r\n\\=, "), NVCT); // duplicates TestParseDisplayName("foo, Version=1.0.0.0, Version=1.0.0.0", null); TestParseDisplayName("foo, Version=1.0.0.0, Version=2.0.0.0", null); TestParseDisplayName("foo, Culture=neutral, Version=1.0.0.0, Culture=en-US", null); }
/// <summary> /// Handles the <see cref="AppDomain.AssemblyResolve"/> event when the requesting /// assembly is one that we've loaded. /// /// We assume that an assembly's dependencies can be found next to it in the file /// system. /// </summary> private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) { if (args.RequestingAssembly == null) { // We don't know who is requesting the load; don't try to satisfy the request. return(null); } lock (s_guard) { string requestingAssemblyName = args.RequestingAssembly.FullName; string requestingAssemblyFullPath; if (!s_filesFromAssemblyNames.TryGetValue(requestingAssemblyName, out requestingAssemblyFullPath)) { // The requesting assembly is not one of ours; don't try to satisfy the request. return(null); } string nameWithPolicyApplied = AppDomain.CurrentDomain.ApplyPolicy(args.Name); Assembly assembly; if (s_assembliesFromNames.TryGetValue(nameWithPolicyApplied, out assembly)) { // We've already loaded an assembly by this name; use that. return(assembly); } AssemblyIdentity assemblyIdentity; if (!AssemblyIdentity.TryParseDisplayName(nameWithPolicyApplied, out assemblyIdentity)) { return(null); } string directoryPath = Path.GetDirectoryName(requestingAssemblyFullPath); string assemblyFullPath = Path.Combine(directoryPath, assemblyIdentity.Name + ".dll"); assembly = LoadCore(assemblyFullPath); s_requestingFilesFromFiles[assemblyFullPath] = requestingAssemblyFullPath; return(assembly); } }
/// <summary> /// Attempts to find and load an <see cref="Assembly"/> when the requesting <see cref="Assembly"/> /// is known. /// </summary> /// <remarks> /// This method differs from <see cref="ResolveForUnknownRequestor(string)"/> in a couple of ways. /// First, we only attempt to handle the load if the requesting assembly is one we've loaded. /// If it isn't one of ours, then presumably some other component is hooking <see cref="AppDomain.AssemblyResolve"/> /// and will have a better idea of how to load the assembly. /// Second, we only look immediately next to the requesting assembly, instead of next to all the assemblies /// we've previously loaded. An analyzer needs to ship with all of its dependencies, and if it doesn't we don't /// want to mask the problem. /// </remarks> private static Assembly ResolveForKnownRequestor(string requestedAssemblyName, Assembly requestingAssembly) { lock (s_guard) { string requestingAssemblyName = requestingAssembly.FullName; string requestingAssemblyFullPath; if (!s_filesFromAssemblyNames.TryGetValue(requestingAssemblyName, out requestingAssemblyFullPath)) { // The requesting assembly is not one of ours; don't try to satisfy the request. return(null); } string nameWithPolicyApplied = AppDomain.CurrentDomain.ApplyPolicy(requestedAssemblyName); Assembly assembly; if (s_assembliesFromNames.TryGetValue(nameWithPolicyApplied, out assembly)) { // We've already loaded an assembly by this name; use that. return(assembly); } AssemblyIdentity assemblyIdentity; if (!AssemblyIdentity.TryParseDisplayName(nameWithPolicyApplied, out assemblyIdentity)) { return(null); } string directoryPath = Path.GetDirectoryName(requestingAssemblyFullPath); string assemblyFullPath = Path.Combine(directoryPath, assemblyIdentity.Name + ".dll"); if (!File.Exists(assemblyFullPath)) { return(null); } assembly = LoadCore(assemblyFullPath); s_requestingFilesFromFiles[assemblyFullPath] = requestingAssemblyFullPath; return(assembly); } }
public Assembly Load(string displayName) { if (!AssemblyIdentity.TryParseDisplayName(displayName, out var requestedIdentity)) { return(null); } ImmutableArray <string> candidatePaths; lock (_guard) { // First, check if this loader already loaded the requested assembly: if (_loadedAssembliesByIdentity.TryGetValue(requestedIdentity, out var existingAssembly)) { return(existingAssembly); } // Second, check if an assembly file of the same simple name was registered with the loader: if (!_knownAssemblyPathsBySimpleName.TryGetValue(requestedIdentity.Name, out var pathList)) { return(null); } Debug.Assert(pathList.Count > 0); candidatePaths = pathList.ToImmutableArray(); } // Multiple assemblies of the same simple name but different identities might have been registered. // Load the one that matches the requested identity (if any). foreach (var candidatePath in candidatePaths) { var candidateIdentity = GetOrAddAssemblyIdentity(candidatePath); if (requestedIdentity.Equals(candidateIdentity)) { return(LoadFromPathUncheckedCore(candidatePath, candidateIdentity)); } } return(null); }
private static ImmutableDictionary <IAssemblySymbol, ImmutableSortedSet <string> > GetRestrictedInternalsVisibleToMap(Compilation compilation) { var restrictedInternalsVisibleToAttribute = compilation.GetTypeByMetadataName("System.Runtime.CompilerServices.RestrictedInternalsVisibleToAttribute"); if (restrictedInternalsVisibleToAttribute == null) { return(ImmutableDictionary <IAssemblySymbol, ImmutableSortedSet <string> > .Empty); } var builder = ImmutableDictionary.CreateBuilder <IAssemblySymbol, ImmutableSortedSet <string> >(); foreach (var referencedAssemblySymbol in compilation.References.Select(compilation.GetAssemblyOrModuleSymbol).OfType <IAssemblySymbol>()) { // Check IVT if (!referencedAssemblySymbol.GivesAccessTo(compilation.Assembly)) { continue; } var namespaceNameComparer = compilation.IsCaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase; var namespaceBuilder = ImmutableSortedSet.CreateBuilder(namespaceNameComparer); foreach (var assemblyAttribute in referencedAssemblySymbol.GetAttributes()) { // Look for ctor: "RestrictedInternalsVisibleToAttribute(string assemblyName, params string[] namespaces)" if (!Equals(assemblyAttribute.AttributeClass, restrictedInternalsVisibleToAttribute) || assemblyAttribute.AttributeConstructor.Parameters.Length != 2 || assemblyAttribute.AttributeConstructor.Parameters[0].Type.SpecialType != SpecialType.System_String || !(assemblyAttribute.AttributeConstructor.Parameters[1].Type is IArrayTypeSymbol arrayType) || arrayType.Rank != 1 || arrayType.ElementType.SpecialType != SpecialType.System_String || !assemblyAttribute.AttributeConstructor.Parameters[1].IsParams) { continue; } // Ensure the Restricted IVT is for the current compilation's assembly. if (assemblyAttribute.ConstructorArguments.Length != 2 || assemblyAttribute.ConstructorArguments[0].Kind != TypedConstantKind.Primitive || !(assemblyAttribute.ConstructorArguments[0].Value is string assemblyName) || !AssemblyIdentity.TryParseDisplayName(assemblyName, out var assemblyIdentity) || AssemblyIdentityComparer.Default.Compare(assemblyIdentity, compilation.Assembly.Identity) == AssemblyIdentityComparer.ComparisonResult.NotEquivalent) { continue; } // Ensure second constructor argument is string array. if (assemblyAttribute.ConstructorArguments[1].Kind != TypedConstantKind.Array || !(assemblyAttribute.ConstructorArguments[1].Values is var namespaceConstants)) { continue; } // Add namespaces specified in the second constructor argument. foreach (TypedConstant namespaceConstant in namespaceConstants) { if (namespaceConstant.Kind == TypedConstantKind.Primitive && namespaceConstant.Value is string namespaceName) { namespaceBuilder.Add(namespaceName); } } } if (namespaceBuilder.Count > 0) { builder.Add(referencedAssemblySymbol, namespaceBuilder.ToImmutable()); } } return(builder.ToImmutable()); }
public static MethodDebugInfo GetMethodDebugInfo( this ISymUnmanagedReader reader, int methodToken, int methodVersion, ArrayBuilder <ISymUnmanagedScope> scopes) { ImmutableArray <string> externAliasStrings; var importStringGroups = reader.GetCSharpGroupedImportStrings(methodToken, methodVersion, out externAliasStrings); Debug.Assert(importStringGroups.IsDefault == externAliasStrings.IsDefault); ArrayBuilder <ImmutableArray <ImportRecord> > importRecordGroupBuilder = null; ArrayBuilder <ExternAliasRecord> externAliasRecordBuilder = null; if (!importStringGroups.IsDefault) { importRecordGroupBuilder = ArrayBuilder <ImmutableArray <ImportRecord> > .GetInstance(importStringGroups.Length); foreach (var importStringGroup in importStringGroups) { var groupBuilder = ArrayBuilder <ImportRecord> .GetInstance(importStringGroup.Length); foreach (var importString in importStringGroup) { ImportRecord record; if (NativeImportRecord.TryCreateFromCSharpImportString(importString, out record)) { groupBuilder.Add(record); } else { Debug.WriteLine($"Failed to parse import string {importString}"); } } importRecordGroupBuilder.Add(groupBuilder.ToImmutableAndFree()); } if (!externAliasStrings.IsDefault) { externAliasRecordBuilder = ArrayBuilder <ExternAliasRecord> .GetInstance(externAliasStrings.Length); foreach (string externAliasString in externAliasStrings) { string alias; string externAlias; string target; ImportTargetKind kind; if (!CustomDebugInfoReader.TryParseCSharpImportString(externAliasString, out alias, out externAlias, out target, out kind)) { Debug.WriteLine($"Unable to parse extern alias '{externAliasString}'"); continue; } Debug.Assert(kind == ImportTargetKind.Assembly, "Programmer error: How did a non-assembly get in the extern alias list?"); Debug.Assert(alias != null); // Name of the extern alias. Debug.Assert(externAlias == null); // Not used. Debug.Assert(target != null); // Name of the target assembly. AssemblyIdentity targetIdentity; if (!AssemblyIdentity.TryParseDisplayName(target, out targetIdentity)) { Debug.WriteLine($"Unable to parse target of extern alias '{externAliasString}'"); continue; } externAliasRecordBuilder.Add(new NativeExternAliasRecord <AssemblySymbol>(alias, targetIdentity)); } } } var hoistedLocalScopeRecords = ImmutableArray <HoistedLocalScopeRecord> .Empty; var dynamicLocalMap = ImmutableDictionary <int, ImmutableArray <bool> > .Empty; var dynamicLocalConstantMap = ImmutableDictionary <string, ImmutableArray <bool> > .Empty; byte[] customDebugInfoBytes = reader.GetCustomDebugInfoBytes(methodToken, methodVersion); if (customDebugInfoBytes != null) { var customDebugInfoRecord = CustomDebugInfoReader.TryGetCustomDebugInfoRecord(customDebugInfoBytes, CustomDebugInfoKind.StateMachineHoistedLocalScopes); if (!customDebugInfoRecord.IsDefault) { hoistedLocalScopeRecords = CustomDebugInfoReader.DecodeStateMachineHoistedLocalScopesRecord(customDebugInfoRecord) .SelectAsArray(s => HoistedLocalScopeRecord.FromNative(s.StartOffset, s.EndOffset)); } CustomDebugInfoReader.GetCSharpDynamicLocalInfo( customDebugInfoBytes, methodToken, methodVersion, scopes, out dynamicLocalMap, out dynamicLocalConstantMap); } return(new MethodDebugInfo( hoistedLocalScopeRecords, importRecordGroupBuilder?.ToImmutableAndFree() ?? ImmutableArray <ImmutableArray <ImportRecord> > .Empty, externAliasRecordBuilder?.ToImmutableAndFree() ?? ImmutableArray <ExternAliasRecord> .Empty, dynamicLocalMap, dynamicLocalConstantMap, defaultNamespaceName: "")); // Unused in C#. }
public static MethodDebugInfo GetMethodDebugInfo( this ISymUnmanagedReader reader, int methodToken, int methodVersion) { ImmutableArray <string> externAliasStrings; var importStringGroups = reader.GetCSharpGroupedImportStrings(methodToken, methodVersion, out externAliasStrings); Debug.Assert(importStringGroups.IsDefault == externAliasStrings.IsDefault); if (importStringGroups.IsDefault) { return(default(MethodDebugInfo)); } var importRecordGroupBuilder = ArrayBuilder <ImmutableArray <ImportRecord> > .GetInstance(importStringGroups.Length); foreach (var importStringGroup in importStringGroups) { var groupBuilder = ArrayBuilder <ImportRecord> .GetInstance(importStringGroup.Length); foreach (var importString in importStringGroup) { ImportRecord record; if (NativeImportRecord.TryCreateFromCSharpImportString(importString, out record)) { groupBuilder.Add(record); } else { Debug.WriteLine($"Failed to parse import string {importString}"); } } importRecordGroupBuilder.Add(groupBuilder.ToImmutableAndFree()); } var externAliasRecordBuilder = ArrayBuilder <ExternAliasRecord> .GetInstance(externAliasStrings.Length); foreach (string externAliasString in externAliasStrings) { string alias; string externAlias; string target; ImportTargetKind kind; if (!CustomDebugInfoReader.TryParseCSharpImportString(externAliasString, out alias, out externAlias, out target, out kind)) { Debug.WriteLine($"Unable to parse extern alias '{externAliasString}'"); continue; } Debug.Assert(kind == ImportTargetKind.Assembly, "Programmer error: How did a non-assembly get in the extern alias list?"); Debug.Assert(alias != null); // Name of the extern alias. Debug.Assert(externAlias == null); // Not used. Debug.Assert(target != null); // Name of the target assembly. AssemblyIdentity targetIdentity; if (!AssemblyIdentity.TryParseDisplayName(target, out targetIdentity)) { Debug.WriteLine($"Unable to parse target of extern alias '{externAliasString}'"); continue; } externAliasRecordBuilder.Add(new NativeExternAliasRecord <AssemblySymbol>(alias, targetIdentity)); } return(new MethodDebugInfo( importRecordGroupBuilder.ToImmutableAndFree(), externAliasRecordBuilder.ToImmutableAndFree(), defaultNamespaceName: "")); // Unused in C#. }
public static string DumpAssemblyData(IEnumerable <ModuleData> modules, out string dumpDirectory) { dumpDirectory = null; StringBuilder sb = new StringBuilder(); foreach (var module in modules) { // Limit the number of dumps to 10. After 10 we're likely in a bad state and are // dumping lots of unnecessary data. if (s_dumpCount > 10) { break; } if (module.InMemoryModule) { Interlocked.Increment(ref s_dumpCount); if (dumpDirectory == null) { dumpDirectory = Path.GetTempPath(); try { Directory.CreateDirectory(dumpDirectory); } catch { // Okay if directory already exists } } string fileName; if (module.Kind == OutputKind.NetModule) { fileName = module.FullName; } else { AssemblyIdentity.TryParseDisplayName(module.FullName, out var identity); fileName = identity.Name; } string pePath = Path.Combine(dumpDirectory, fileName + module.Kind.GetDefaultExtension()); string pdbPath = (module.Pdb != null) ? pdbPath = Path.Combine(dumpDirectory, fileName + ".pdb") : null; try { module.Image.WriteToFile(pePath); if (pdbPath != null) { module.Pdb.WriteToFile(pdbPath); } } catch (IOException) { pePath = "<unable to write file>"; if (pdbPath != null) { pdbPath = "<unable to write file>"; } } sb.Append("PE(" + module.Kind + "): "); sb.AppendLine(pePath); if (pdbPath != null) { sb.Append("PDB: "); sb.AppendLine(pdbPath); } } } return(sb.ToString()); }
private static List <RazorEngineAssembly> GetRazorCustomizationAssemblies(Compilation compilation) { // The goal here is to find the set of assemblies + paths that have some kind of // Razor extensibility. // // We do that by making a compilation and then looking through the set of assembly names // (AssemblyIdentity) and references to dlls on disk (PortableExecutableReference) to find // uses of RazorEngineCustomizationAttribute and RazorEngineDependencyAttribute. // // We're limited to supporting files on disk because we will need to shadow copy them // and manually load them. // // Also note that we're not doing anything here to explicitly uniquify this list, since // we're limiting the set of candidates to the set of assemblies used for compilation, which // has already been processed by Roslyn. var results = new List <RazorEngineAssembly>(); // The RazorEngineDependencyAttribute also allows specifying an assembly name to go along // with a piece of extensibility. We'll collect these on the first pass through the assemblies // and then look those up by name. var unresolvedIdentities = new List <AssemblyIdentity>(); foreach (var reference in compilation.References) { var peReference = reference as PortableExecutableReference; if (peReference == null || peReference.FilePath == null) { // No path, can't load it. continue; } var assemblySymbol = compilation.GetAssemblyOrModuleSymbol(reference) as IAssemblySymbol; if (assemblySymbol == null) { // It's unlikely, but possible that a reference might be a module instead of an assembly. // We can't load that, so just skip it. continue; } var identity = assemblySymbol.Identity; if (identity.Name == RazorAssemblyName) { // This is the main Razor assembly. results.Add(new RazorEngineAssembly(identity, peReference.FilePath)); } // Now we're looking for the Razor exensibility attributes. var attributes = assemblySymbol.GetAttributes(); for (var i = 0; i < attributes.Length; i++) { var attribute = attributes[i]; var name = attribute.AttributeClass.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); if (string.Equals( CustomizationAttribute, name, StringComparison.Ordinal)) { results.Add(new RazorEngineAssembly(identity, peReference.FilePath)); } if (string.Equals( DependencyAttribute, name, StringComparison.Ordinal)) { // This attribute refers to a separate assembly for which we will need to resolve a path. // // Ignore parsing failures here. AssemblyIdentity dependency; if (AssemblyIdentity.TryParseDisplayName((string)attribute.ConstructorArguments[0].Value, out dependency)) { unresolvedIdentities.Add(dependency); } } } } // Now we need to do another pass to resolve all the unresolved names. if (unresolvedIdentities.Count > 0) { //while (identities.MoveNext() && references.MoveNext()) //{ // var peReference = references.Current as PortableExecutableReference; // if (peReference == null || peReference.FilePath == null) // { // // No path, can't load it. // continue; // } // var assemblySymbol = compilation.GetAssemblyOrModuleSymbol(peReference) as IAssemblySymbol; // if (assemblySymbol == null) // { // // It's unlikely, but possible that a reference might be a module instead of an assembly. // // We can't load that, so just skip it. // continue; // } // for (var i = 0; i < unresolvedIdentities.Count; i++) // { // // Note: argument ordering here is significant. We expect that the attribute will often refer to a // // partial name and omit details like the version and public-key, therefore the value from the // // attribute must be the first argument. // if (AssemblyIdentityComparer.Default.ReferenceMatchesDefinition( // unresolvedIdentities[i], // identities.Current)) // { // results.Add(new RazorEngineAssembly(identities.Current, peReference.FilePath)); // break; // } // } //} } return(results); }
private static void ReadCSharpNativeImportsInfo( ISymUnmanagedReader3 reader, EESymbolProvider <TTypeSymbol, TLocalSymbol> symbolProvider, int methodToken, int methodVersion, out ImmutableArray <ImmutableArray <ImportRecord> > importRecordGroups, out ImmutableArray <ExternAliasRecord> externAliasRecords) { ImmutableArray <string> externAliasStrings; var importStringGroups = CustomDebugInfoReader.GetCSharpGroupedImportStrings( methodToken, KeyValuePair.Create(reader, methodVersion), getMethodCustomDebugInfo: (token, arg) => GetCustomDebugInfoBytes(arg.Key, token, arg.Value), getMethodImportStrings: (token, arg) => GetImportStrings(arg.Key, token, arg.Value), externAliasStrings: out externAliasStrings); Debug.Assert(importStringGroups.IsDefault == externAliasStrings.IsDefault); ArrayBuilder <ImmutableArray <ImportRecord> > importRecordGroupBuilder = null; ArrayBuilder <ExternAliasRecord> externAliasRecordBuilder = null; if (!importStringGroups.IsDefault) { importRecordGroupBuilder = ArrayBuilder <ImmutableArray <ImportRecord> > .GetInstance(importStringGroups.Length); foreach (var importStringGroup in importStringGroups) { var groupBuilder = ArrayBuilder <ImportRecord> .GetInstance(importStringGroup.Length); foreach (var importString in importStringGroup) { ImportRecord record; if (TryCreateImportRecordFromCSharpImportString(symbolProvider, importString, out record)) { groupBuilder.Add(record); } else { Debug.WriteLine($"Failed to parse import string {importString}"); } } importRecordGroupBuilder.Add(groupBuilder.ToImmutableAndFree()); } if (!externAliasStrings.IsDefault) { externAliasRecordBuilder = ArrayBuilder <ExternAliasRecord> .GetInstance(externAliasStrings.Length); foreach (string externAliasString in externAliasStrings) { string alias; string externAlias; string target; ImportTargetKind kind; if (!CustomDebugInfoReader.TryParseCSharpImportString(externAliasString, out alias, out externAlias, out target, out kind)) { Debug.WriteLine($"Unable to parse extern alias '{externAliasString}'"); continue; } Debug.Assert(kind == ImportTargetKind.Assembly, "Programmer error: How did a non-assembly get in the extern alias list?"); Debug.Assert(alias != null); // Name of the extern alias. Debug.Assert(externAlias == null); // Not used. Debug.Assert(target != null); // Name of the target assembly. AssemblyIdentity targetIdentity; if (!AssemblyIdentity.TryParseDisplayName(target, out targetIdentity)) { Debug.WriteLine($"Unable to parse target of extern alias '{externAliasString}'"); continue; } externAliasRecordBuilder.Add(new ExternAliasRecord(alias, targetIdentity)); } } } importRecordGroups = importRecordGroupBuilder?.ToImmutableAndFree() ?? ImmutableArray <ImmutableArray <ImportRecord> > .Empty; externAliasRecords = externAliasRecordBuilder?.ToImmutableAndFree() ?? ImmutableArray <ExternAliasRecord> .Empty; }
private static string GetReferenceString(Reference reference) { if (!reference.StrongName) { return(reference.Path); } string name = reference.Name; if (name == "mscorlib") { // mscorlib is always loaded return(null); } // TODO: This shouldn't directly depend on GAC, rather we should have some kind of "reference simplifier". var possibleGacNames = GlobalAssemblyCache.GetAssemblyIdentities(name).ToArray(); if (possibleGacNames.Length == 0) { // no assembly with simple "name" found in GAC, use path to identify the reference: return(reference.Path); } string version = reference.Version; string culture = reference.Culture; string publicKeyToken = reference.PublicKeyToken; var fullName = string.Concat( name, ", Version=", version, ", Culture=", (culture == "") ? "neutral" : culture, ", PublicKeyToken=", publicKeyToken.ToLowerInvariant()); AssemblyIdentity identity; if (!AssemblyIdentity.TryParseDisplayName(fullName, out identity)) { // ignore invalid names: return(null); } var foundEquivalent = false; var foundNonEquivalent = false; foreach (var possibleGacName in possibleGacNames) { if (DesktopAssemblyIdentityComparer.Default.ReferenceMatchesDefinition(identity, possibleGacName)) { foundEquivalent = true; } else { foundNonEquivalent = true; } if (foundEquivalent && foundNonEquivalent) { break; } } if (!foundEquivalent) { // The reference name isn't equivalent to any GAC name. // The assembly is strong named but not GAC'd, so we need to load it from path: return(reference.Path); } if (foundNonEquivalent) { // We found some equivalent assemblies but also some non-equivalent. // So simple name doesn't identify the reference uniquely. return(fullName); } // We found a single simple name match that is equivalent to the given reference. // We can use the simple name to load the GAC'd assembly. return(name); }