Example #1
0
        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);
            }
        }
Example #2
0
        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));
        }
Example #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));
        }
Example #7
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));
        }
Example #10
0
        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());
Example #11
0
        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);
        }
Example #13
0
 static INamedTypeSymbol GetTypeByMetadataNameOrThrow(IAssemblySymbol assemblySymbol, string fullyQualifiedMetadataName) =>
 assemblySymbol.GetTypeByMetadataName(fullyQualifiedMetadataName)
 ?? throw new InvalidOperationException($"Type with metadata '{fullyQualifiedMetadataName}' not found");