internal static INamedTypeSymbol GetTypeByMetadataName(this IAssemblySymbol assembly, string fullyQualifiedMetadataName, bool ignoreCase) { if (!ignoreCase) { return(assembly.GetTypeByMetadataName(fullyQualifiedMetadataName)); } return(assembly.GetTypeByMetadataName(fullyQualifiedMetadataName) ?? GetTypeByMetadataNameIgnoreCase(assembly.GlobalNamespace)); INamedTypeSymbol GetTypeByMetadataNameIgnoreCase(INamespaceSymbol ns) { if (fullyQualifiedMetadataName.StartsWith(ns.MetadataName, StringComparison.OrdinalIgnoreCase)) { foreach (var candidate in ns.GetTypeMembers()) { if (fullyQualifiedMetadataName.EndsWith(candidate.MetadataName, StringComparison.OrdinalIgnoreCase) && string.Equals(candidate.QualifiedMetadataName(), fullyQualifiedMetadataName, StringComparison.OrdinalIgnoreCase)) { return(candidate); } } foreach (var nested in ns.GetNamespaceMembers()) { if (GetTypeByMetadataNameIgnoreCase(nested) is INamedTypeSymbol match) { return(match); } } } return(null); } }
public static Version GetDotNetFrameworkVersion(Compilation compilation) { if (compilation == null || !IsTypeDeclaredInExpectedAssembly(compilation, "System.String", "mscorlib").GetValueOrDefault()) { return(null); } IAssemblySymbol mscorlibAssembly = compilation.GetSpecialType(SpecialType.System_String).ContainingAssembly; if (mscorlibAssembly.Identity.Version.Major < 4) { return(mscorlibAssembly.Identity.Version); } if (mscorlibAssembly.GetTypeByMetadataName(WellKnownTypeNames.SystemAppContext) != null) { return(new Version(4, 6)); } INamedTypeSymbol typeSymbol = mscorlibAssembly.GetTypeByMetadataName(WellKnownTypeNames.SystemIOUnmanagedMemoryStream); if (!typeSymbol.GetMembers("FlushAsync").IsEmpty) { return(new Version(4, 5, 2)); } typeSymbol = mscorlibAssembly.GetTypeByMetadataName(WellKnownTypeNames.SystemDiagnosticsTracingEventSource); if (typeSymbol != null) { return(typeSymbol.GetMembers("CurrentThreadActivityId").IsEmpty ? new Version(4, 5) : new Version(4, 5, 1)); } return(new Version(4, 0)); }
public static (bool dotnetCore, Version version) GetDotNetFrameworkVersion(this Compilation compilation) { if (IsTypeDeclaredInExpectedAssembly(compilation, "System.String", "System.Runtime").GetValueOrDefault()) { return(true, null); // ideally would get .NET Core version, but not implemented since not needed yet } if (!IsTypeDeclaredInExpectedAssembly(compilation, "System.String", "mscorlib").GetValueOrDefault()) { return(false, null); } IAssemblySymbol mscorlibAssembly = compilation.GetTypeByMetadataName("System.String").ContainingAssembly; if (mscorlibAssembly.Identity.Version.Major < 4) { return(false, mscorlibAssembly.Identity.Version); } if (mscorlibAssembly.GetTypeByMetadataName("System.Diagnostics.Tracing.EventSourceCreatedEventArgs") != null) { return(false, new Version(4, 6, 2)); } if (!IsTypeDeclaredInExpectedAssembly(compilation, "System.Net.TransportContext", "System").GetValueOrDefault()) { return(false, null); } IAssemblySymbol systemAssembly = compilation.GetTypeByMetadataName("System.Net.TransportContext").ContainingAssembly; INamedTypeSymbol typeSymbol = systemAssembly.GetTypeByMetadataName("System.Net.TransportContext"); if (!typeSymbol.GetMembers("GetTlsTokenBindings").IsEmpty) { return(false, new Version(4, 6, 1)); } if (mscorlibAssembly.GetTypeByMetadataName("System.AppContext") != null) { return(false, new Version(4, 6)); } typeSymbol = mscorlibAssembly.GetTypeByMetadataName("System.IO.UnmanagedMemoryStream"); if (!typeSymbol.GetMembers("FlushAsync").IsEmpty) { return(false, new Version(4, 5, 2)); } typeSymbol = mscorlibAssembly.GetTypeByMetadataName("System.Diagnostics.Tracing.EventSource"); if (typeSymbol != null) { return(false, typeSymbol.GetMembers("CurrentThreadActivityId").IsEmpty ? new Version(4, 5) : new Version(4, 5, 1)); } return(false, new Version(4, 0)); }
private static ISymbol ResolveTarget(Compilation withAllSymbols, Compilation symbolSource, IAssemblySymbol assembly, ISymbol symbol) { switch (symbol) { case INamedTypeSymbol type: /*switch (type.TypeKind) * { * case TypeKind.Class: * case TypeKind.Enum: * case TypeKind.Interface: * case TypeKind.Struct: * return assembly?.GetTypeByMetadataName(GetName(compilation, symbol)); * case TypeKind.Array: * // TODO * case TypeKind.Error: * case TypeKind.Unknown: * return null; * }*/ return(assembly?.GetTypeByMetadataName(GetName(symbolSource, symbol))); case IMethodSymbol method: //IEnumerable<ITypeSymbol> parameters = method.Parameters.Select(p => ResolveTarget(compilation, compilation.Assembly, p.Type) as ITypeSymbol ?? p.Type); //return ((ITypeSymbol)ResolveTarget(compilation, assembly, symbol.ContainingType))?.GetMembers(GetName(compilation, symbol)).FirstOrDefault(s => s is IMethodSymbol m && m.Parameters.Zip(parameters, (a, b) => a.Type.Equals(b)).All(b => b)); return(((ITypeSymbol)ResolveTarget(withAllSymbols, symbolSource, assembly, symbol.ContainingType))?.GetBaseTypesAndThis().SelectMany(t => t.GetMembers(GetName(symbolSource, symbol))).FirstOrDefault(s => s is IMethodSymbol m && CompareParameters(withAllSymbols, symbolSource, m.Parameters, method.Parameters))); default: return(((ITypeSymbol)ResolveTarget(withAllSymbols, symbolSource, assembly, symbol.ContainingType))?.GetBaseTypesAndThis().SelectMany(t => t.GetMembers(GetName(symbolSource, symbol))).FirstOrDefault()); } }
private Type?ResolveFromAssembly(Type type, IAssemblySymbol assemblySymbol) { if (type.IsArray) { var typeSymbol = assemblySymbol.GetTypeByMetadataName(type.GetElementType().FullName); if (typeSymbol == null) { return(null !); } return(this._Compilation.CreateArrayTypeSymbol(typeSymbol).AsType(this)); } // Resolve the full name return(assemblySymbol.GetTypeByMetadataName(type.FullName) !.AsType(this)); }
/// <summary> /// Gets the version of the target .NET framework of the compilation. /// </summary> /// <returns> /// Null if the target framework is not .NET Framework. /// </returns> /// <remarks> /// This method returns the assembly version of mscorlib for .NET Framework prior version 4.0. /// It is using API diff tool to compare new classes in different versions and decide which version it is referencing /// i.e. for .NET framework 3.5, the returned version would be 2.0.0.0. /// For .NET Framework 4.X, this method returns the actual framework version instead of assembly version of mscorlib, /// i.e. for .NET framework 4.5.2, this method return 4.5.2 instead of 4.0.0.0. /// </remarks> public static Version GetDotNetFrameworkVersion(this Compilation compilation) { if (compilation == null || !IsTypeDeclaredInExpectedAssembly(compilation, "System.String", "mscorlib").GetValueOrDefault()) { return(null); } IAssemblySymbol mscorlibAssembly = compilation.GetTypeByMetadataName("System.String").ContainingAssembly; if (mscorlibAssembly.Identity.Version.Major < 4) { return(mscorlibAssembly.Identity.Version); } if (mscorlibAssembly.GetTypeByMetadataName("System.Diagnostics.Tracing.EventSourceCreatedEventArgs") != null) { return(new Version(4, 6, 2)); } if (!IsTypeDeclaredInExpectedAssembly(compilation, "System.Net.TransportContext", "System").GetValueOrDefault()) { return(null); } IAssemblySymbol systemAssembly = compilation.GetTypeByMetadataName("System.Net.TransportContext").ContainingAssembly; INamedTypeSymbol typeSymbol = systemAssembly.GetTypeByMetadataName("System.Net.TransportContext"); if (!typeSymbol.GetMembers("GetTlsTokenBindings").IsEmpty) { return(new Version(4, 6, 1)); } if (mscorlibAssembly.GetTypeByMetadataName("System.AppContext") != null) { return(new Version(4, 6)); } typeSymbol = mscorlibAssembly.GetTypeByMetadataName("System.IO.UnmanagedMemoryStream"); if (!typeSymbol.GetMembers("FlushAsync").IsEmpty) { return(new Version(4, 5, 2)); } typeSymbol = mscorlibAssembly.GetTypeByMetadataName("System.Diagnostics.Tracing.EventSource"); if (typeSymbol != null) { return(typeSymbol.GetMembers("CurrentThreadActivityId").IsEmpty ? new Version(4, 5) : new Version(4, 5, 1)); } return(new Version(4, 0)); }
private ITypeSymbol LookupPlatformSpecificAttribute(IAssemblySymbol assembly) { if (!_platformSpecificAttributes.TryGetValue(assembly, out var result)) { result = assembly.GetTypeByMetadataName("System.Runtime.CompilerServices.PlatformSpecificAttribute"); _platformSpecificAttributes.TryAdd(assembly, result); } return(result); }
public static MarshallingGeneratorFactoryKey <(TargetFramework, Version, LibraryImportGeneratorOptions)> CreateGeneratorFactory(StubEnvironment env, LibraryImportGeneratorOptions options) { IMarshallingGeneratorFactory generatorFactory; if (options.GenerateForwarders) { generatorFactory = new ForwarderMarshallingGeneratorFactory(); } else { if (env.TargetFramework != TargetFramework.Net || env.TargetFrameworkVersion.Major < 7) { // If we're using our downstream support, fall back to the Forwarder marshaller when the TypePositionInfo is unhandled. generatorFactory = new ForwarderMarshallingGeneratorFactory(); } else { // If we're in a "supported" scenario, then emit a diagnostic as our final fallback. generatorFactory = new UnsupportedMarshallingFactory(); } generatorFactory = new NoMarshallingInfoErrorMarshallingFactory(generatorFactory); // The presence of System.Runtime.CompilerServices.DisableRuntimeMarshallingAttribute is tied to TFM, // so we use TFM in the generator factory key instead of the Compilation as the compilation changes on every keystroke. IAssemblySymbol coreLibraryAssembly = env.Compilation.GetSpecialType(SpecialType.System_Object).ContainingAssembly; ITypeSymbol? disabledRuntimeMarshallingAttributeType = coreLibraryAssembly.GetTypeByMetadataName(TypeNames.System_Runtime_CompilerServices_DisableRuntimeMarshallingAttribute); bool runtimeMarshallingDisabled = disabledRuntimeMarshallingAttributeType is not null && env.Compilation.Assembly.GetAttributes().Any(attr => SymbolEqualityComparer.Default.Equals(attr.AttributeClass, disabledRuntimeMarshallingAttributeType)); // Since the char type can go into the P/Invoke signature here, we can only use it when // runtime marshalling is disabled. generatorFactory = new CharMarshallingGeneratorFactory(generatorFactory, useBlittableMarshallerForUtf16: runtimeMarshallingDisabled); InteropGenerationOptions interopGenerationOptions = new(options.UseMarshalType); generatorFactory = new MarshalAsMarshallingGeneratorFactory(interopGenerationOptions, generatorFactory); IMarshallingGeneratorFactory elementFactory = new AttributedMarshallingModelGeneratorFactory( // Since the char type in an array will not be part of the P/Invoke signature, we can // use the regular blittable marshaller in all cases. new CharMarshallingGeneratorFactory(generatorFactory, useBlittableMarshallerForUtf16: true), new AttributedMarshallingModelOptions(runtimeMarshallingDisabled, MarshalMode.ElementIn, MarshalMode.ElementRef, MarshalMode.ElementOut)); // We don't need to include the later generator factories for collection elements // as the later generator factories only apply to parameters. generatorFactory = new AttributedMarshallingModelGeneratorFactory( generatorFactory, elementFactory, new AttributedMarshallingModelOptions(runtimeMarshallingDisabled, MarshalMode.ManagedToUnmanagedIn, MarshalMode.ManagedToUnmanagedRef, MarshalMode.ManagedToUnmanagedOut)); generatorFactory = new ByValueContentsMarshalKindValidator(generatorFactory); } return(MarshallingGeneratorFactoryKey.Create((env.TargetFramework, env.TargetFrameworkVersion, options), generatorFactory)); }
public void GetAssemblyQualifiedName_ShouldDoWhatTheNameSuggests(Type type) { Assembly asm = type.Assembly; CSharpCompilation compilation = CreateCompilation(string.Empty, asm); IAssemblySymbol asmSymbol = (IAssemblySymbol)compilation.GetAssemblyOrModuleSymbol(compilation.References.Single(@ref => @ref.Display == asm.Location)); INamedTypeSymbol typeSymbol = asmSymbol.GetTypeByMetadataName(type.FullName); Assert.That(typeSymbol.GetAssemblyQualifiedName(), Is.EqualTo(type.AssemblyQualifiedName)); }
private static ImmutableArray <IMethodSymbol> GetPotentialMatchingSymbolsFromAssembly( IAssemblySymbol assembly, MultiDictionary <string, string> extensionMethodFilter, ISet <string> namespaceFilter, bool internalsVisible, StatisticCounter counter, CancellationToken cancellationToken) { using var _ = ArrayBuilder <IMethodSymbol> .GetInstance(out var builder); foreach (var(fullyQualifiedContainerName, methodNames) in extensionMethodFilter) { cancellationToken.ThrowIfCancellationRequested(); // First try to filter out types from already imported namespaces var indexOfLastDot = fullyQualifiedContainerName.LastIndexOf('.'); var qualifiedNamespaceName = indexOfLastDot > 0 ? fullyQualifiedContainerName.Substring(0, indexOfLastDot) : string.Empty; if (namespaceFilter.Contains(qualifiedNamespaceName)) { continue; } counter.TotalTypesChecked++; // Container of extension method (static class in C# and Module in VB) can't be generic or nested. var containerSymbol = assembly.GetTypeByMetadataName(fullyQualifiedContainerName); if (containerSymbol == null || !containerSymbol.MightContainExtensionMethods || !IsAccessible(containerSymbol, internalsVisible)) { continue; } foreach (var methodName in methodNames) { var methodSymbols = containerSymbol.GetMembers(methodName).OfType <IMethodSymbol>(); foreach (var methodSymbol in methodSymbols) { counter.TotalExtensionMethodsChecked++; if (methodSymbol.IsExtensionMethod && IsAccessible(methodSymbol, internalsVisible)) { // Find a potential match. builder.Add(methodSymbol); } } } } return(builder.ToImmutable());
private static INamedTypeSymbol GetTypeByMetadataName(this IAssemblySymbol assembly, GenericTypeName genericTypeName, bool ignoreCase) { if (TryGetArgsTypes(out var args)) { return(assembly.GetTypeByMetadataName(genericTypeName.MetadataName, ignoreCase).Construct(args)); } return(null); bool TryGetArgsTypes(out ITypeSymbol[] result) { result = new ITypeSymbol[genericTypeName.TypeArguments.Length]; for (var i = 0; i < genericTypeName.TypeArguments.Length; i++) { var argument = genericTypeName.TypeArguments[i]; if (argument.TypeArguments == null) { var type = GetTypeByMetadataName(assembly, argument.MetadataName, ignoreCase); if (type == null) { return(false); } result[i] = type; } else { var type = GetTypeByMetadataName(assembly, new GenericTypeName(argument.MetadataName, argument.TypeArguments.ToImmutableArray()), ignoreCase); if (type == null) { return(false); } result[i] = type; } } return(true); } }
public TaskInfo CreateTaskInfo( string typeName, string assemblyName, string assemblyFile, string declaredInFile, int declaredAtOffset, IMSBuildEvaluationContext evaluationContext) { //ignore this, it's redundant if (assemblyName != null && assemblyName.StartsWith("Microsoft.Build.Tasks.v", StringComparison.Ordinal)) { return(null); } var tasks = GetTaskAssembly(assemblyName, assemblyFile, declaredInFile, evaluationContext); IAssemblySymbol assembly = tasks?.assembly; if (assembly == null) { //TODO log this? return(null); } string asmShortName; if (string.IsNullOrEmpty(assemblyName)) { asmShortName = Path.GetFileNameWithoutExtension(tasks.Value.path); } else { asmShortName = new AssemblyName(assemblyName).Name; } INamedTypeSymbol FindType(INamespaceSymbol ns, string name) { foreach (var m in ns.GetMembers()) { switch (m) { case INamedTypeSymbol ts: if (ts.Name == name) { return(ts); } continue; case INamespaceSymbol childNs: var found = FindType(childNs, name); if (found != null) { return(found); } continue; } } return(null); } var type = assembly.GetTypeByMetadataName(typeName) ?? FindType(assembly.GlobalNamespace, typeName); if (type == null) { switch (typeName) { case "Microsoft.Build.Tasks.RequiresFramework35SP1Assembly": case "Microsoft.Build.Tasks.ResolveNativeReference": //we don't care about these, they're not present on Mac and they're just noise return(null); } LoggingService.LogWarning($"Did not resolve {typeName}"); return(null); } var ti = new TaskInfo(type.Name, RoslynHelpers.GetDescription(type), type.GetFullName(), assemblyName, assemblyFile, declaredInFile, declaredAtOffset); PopulateTaskInfoFromType(ti, type); return(ti); }
static INamedTypeSymbol GetTypeByMetadataNameOrThrow(IAssemblySymbol assemblySymbol, string fullyQualifiedMetadataName) => assemblySymbol.GetTypeByMetadataName(fullyQualifiedMetadataName) ?? throw new InvalidOperationException($"Type with metadata '{fullyQualifiedMetadataName}' not found");