internal sealed record IncrementalStubGenerationContext(
     StubEnvironment Environment,
     DllImportStubContext StubContext,
     ImmutableArray <AttributeSyntax> ForwardedAttributes,
     GeneratedDllImportData DllImportData,
     ImmutableArray <Diagnostic> Diagnostics)
 {
Esempio n. 2
0
 internal sealed record IncrementalStubGenerationContext(
     StubEnvironment Environment,
     JSSignatureContext SignatureContext,
     ContainingSyntaxContext ContainingSyntaxContext,
     ContainingSyntax StubMethodSyntaxTemplate,
     MethodSignatureDiagnosticLocations DiagnosticLocation,
     JSExportData JSExportData,
     MarshallingGeneratorFactoryKey <(TargetFramework, Version, JSGeneratorOptions)> GeneratorFactoryKey,
 public bool Equals(IncrementalStubGenerationContext?other)
 {
     return(other is not null &&
            StubEnvironment.AreCompilationSettingsEqual(Environment, other.Environment) &&
            StubContext.Equals(other.StubContext) &&
            DllImportData.Equals(other.DllImportData) &&
            ForwardedAttributes.SequenceEqual(other.ForwardedAttributes, (IEqualityComparer <AttributeSyntax>)SyntaxEquivalentComparer.Instance) &&
            Diagnostics.SequenceEqual(other.Diagnostics));
 }
Esempio n. 4
0
 internal sealed record IncrementalStubGenerationContext(
     StubEnvironment Environment,
     SignatureContext SignatureContext,
     ContainingSyntaxContext ContainingSyntaxContext,
     ContainingSyntax StubMethodSyntaxTemplate,
     MethodSignatureDiagnosticLocations DiagnosticLocation,
     ImmutableArray <AttributeSyntax> ForwardedAttributes,
     LibraryImportData LibraryImportData,
     MarshallingGeneratorFactoryKey <(TargetFramework, Version, LibraryImportGeneratorOptions)> GeneratorFactoryKey,
Esempio n. 5
0
 public bool Equals(IncrementalStubGenerationContext?other)
 {
     return(other is not null &&
            StubEnvironment.AreCompilationSettingsEqual(Environment, other.Environment) &&
            SignatureContext.Equals(other.SignatureContext) &&
            ContainingSyntaxContext.Equals(other.ContainingSyntaxContext) &&
            StubMethodSyntaxTemplate.Equals(other.StubMethodSyntaxTemplate) &&
            JSExportData.Equals(other.JSExportData) &&
            DiagnosticLocation.Equals(DiagnosticLocation) &&
            GeneratorFactoryKey.Equals(other.GeneratorFactoryKey) &&
            Diagnostics.SequenceEqual(other.Diagnostics));
 }
Esempio n. 6
0
 public bool Equals(IncrementalStubGenerationContext?other)
 {
     return(other is not null &&
            StubEnvironment.AreCompilationSettingsEqual(Environment, other.Environment) &&
            SignatureContext.Equals(other.SignatureContext) &&
            ContainingSyntaxContext.Equals(other.ContainingSyntaxContext) &&
            StubMethodSyntaxTemplate.Equals(other.StubMethodSyntaxTemplate) &&
            LibraryImportData.Equals(other.LibraryImportData) &&
            DiagnosticLocation.Equals(DiagnosticLocation) &&
            ForwardedAttributes.SequenceEqual(other.ForwardedAttributes, (IEqualityComparer <AttributeSyntax>)SyntaxEquivalentComparer.Instance) &&
            GeneratorFactoryKey.Equals(other.GeneratorFactoryKey) &&
            Diagnostics.SequenceEqual(other.Diagnostics));
 }
        public void Resolve_NullHomeOverrideAndNoEnvVarSet_ReturnsDefaultLocation()
        {
            var config = new GpgConfig {
                GnupghomeOverride = null
            };
            var environment = StubEnvironment.Create()
                              .WithSpecialFolder(Environment.SpecialFolder.ApplicationData, @"C:\Users\Test\AppData")
                              .Build();
            var resolver = new GpgHomedirResolver(config, environment, new MockFileSystem());

            var homeDir = resolver.GetHomeDir();

            homeDir.ShouldBe(@"C:\Users\Test\AppData\gnupg");
        }
        public void Resolve_HomeOverrideSet_ReturnsHomeOverride()
        {
            var config = new GpgConfig {
                GnupghomeOverride = @"C:\Users\Test\.gpg"
            };
            var environment = StubEnvironment.Create()
                              .WithSpecialFolder(Environment.SpecialFolder.ApplicationData, @"C:\Users\Test\AppData")
                              .WithEnvironmentVariable("GNUPGHOME", @"C:\gpg")
                              .Build();
            var resolver = new GpgHomedirResolver(config, environment, new MockFileSystem());

            var homeDir = resolver.GetHomeDir();

            homeDir.ShouldBe(@"C:\Users\Test\.gpg");
        }
Esempio n. 9
0
        public JSImportCodeGenerator(
            StubEnvironment environment,
            ImmutableArray <TypePositionInfo> argTypes,
            JSImportData attributeData,
            JSSignatureContext signatureContext,
            Action <TypePositionInfo, MarshallingNotSupportedException> marshallingNotSupportedCallback,
            IMarshallingGeneratorFactory generatorFactory)
        {
            _signatureContext = signatureContext;
            ManagedToNativeStubCodeContext innerContext = new ManagedToNativeStubCodeContext(environment, ReturnIdentifier, ReturnIdentifier);

            _context     = new JSImportCodeContext(attributeData, innerContext);
            _marshallers = new BoundGenerators(argTypes, CreateGenerator);
            if (_marshallers.ManagedReturnMarshaller.Generator.UsesNativeIdentifier(_marshallers.ManagedReturnMarshaller.TypeInfo, null))
            {
                // If we need a different native return identifier, then recreate the context with the correct identifier before we generate any code.
                innerContext = new ManagedToNativeStubCodeContext(environment, ReturnIdentifier, ReturnNativeIdentifier);
                _context     = new JSImportCodeContext(attributeData, innerContext);
                _marshallers = new BoundGenerators(argTypes, CreateGenerator);
            }

            // validate task + span mix
            if (_marshallers.ManagedReturnMarshaller.TypeInfo.ManagedType is JSTaskTypeInfo)
            {
                BoundGenerator spanArg = _marshallers.AllMarshallers.FirstOrDefault(m => m.TypeInfo.ManagedType is JSSpanTypeInfo);
                if (spanArg != default)
                {
                    marshallingNotSupportedCallback(spanArg.TypeInfo, new MarshallingNotSupportedException(spanArg.TypeInfo, _context)
                    {
                        NotSupportedDetails = SR.SpanAndTaskNotSupported
                    });
                }
            }


            IMarshallingGenerator CreateGenerator(TypePositionInfo p)
            {
                try
                {
                    return(generatorFactory.Create(p, _context));
                }
                catch (MarshallingNotSupportedException e)
                {
                    marshallingNotSupportedCallback(p, e);
                    return(new EmptyJSGenerator());
                }
            }
        }
Esempio n. 10
0
        internal static bool MethodIsSkipLocalsInit(StubEnvironment env, IMethodSymbol method)
        {
            if (env.ModuleSkipLocalsInit)
            {
                return(true);
            }

            if (method.GetAttributes().Any(IsSkipLocalsInitAttribute))
            {
                return(true);
            }

            for (INamedTypeSymbol type = method.ContainingType; type is not null; type = type.ContainingType)
            {
                if (type.GetAttributes().Any(IsSkipLocalsInitAttribute))
                {
                    return(true);
                }
            }

            // We check the module case earlier, so we don't need to do it here.

            return(false);
        public PInvokeStubCodeGenerator(
            StubEnvironment environment,
            ImmutableArray <TypePositionInfo> argTypes,
            bool setLastError,
            Action <TypePositionInfo, MarshallingNotSupportedException> marshallingNotSupportedCallback,
            IMarshallingGeneratorFactory generatorFactory)
        {
            _setLastError = setLastError;

            // Support for SetLastError logic requires .NET 6+. Initialize the
            // supports target framework value with this value.
            if (_setLastError)
            {
                SupportsTargetFramework = environment.TargetFramework == TargetFramework.Net &&
                                          environment.TargetFrameworkVersion.Major >= 6;
            }
            else
            {
                SupportsTargetFramework = true;
            }

            _context     = new ManagedToNativeStubCodeContext(environment, ReturnIdentifier, ReturnIdentifier);
            _marshallers = new BoundGenerators(argTypes, CreateGenerator);

            if (_marshallers.ManagedReturnMarshaller.Generator.UsesNativeIdentifier(_marshallers.ManagedReturnMarshaller.TypeInfo, _context))
            {
                // If we need a different native return identifier, then recreate the context with the correct identifier before we generate any code.
                _context = new ManagedToNativeStubCodeContext(environment, ReturnIdentifier, $"{ReturnIdentifier}{StubCodeContext.GeneratedNativeIdentifierSuffix}");
            }

            bool noMarshallingNeeded = true;

            foreach (BoundGenerator generator in _marshallers.AllMarshallers)
            {
                // Check if marshalling info and generator support the current target framework.
                SupportsTargetFramework &= generator.TypeInfo.MarshallingAttributeInfo is not MissingSupportMarshallingInfo &&
                                           generator.Generator.IsSupported(environment.TargetFramework, environment.TargetFrameworkVersion);

                // Check if generator is either blittable or just a forwarder.
                noMarshallingNeeded &= generator is { Generator : BlittableMarshaller, TypeInfo.IsByRef : false }
                or {
                    Generator : Forwarder
                };
            }

            StubIsBasicForwarder = !setLastError &&
                                   _marshallers.ManagedNativeSameReturn && // If the managed return has native return position, then it's the return for both.
                                   noMarshallingNeeded;

            IMarshallingGenerator CreateGenerator(TypePositionInfo p)
            {
                try
                {
                    return(generatorFactory.Create(p, _context));
                }
                catch (MarshallingNotSupportedException e)
                {
                    marshallingNotSupportedCallback(p, e);
                    return(new Forwarder());
                }
            }
        }
        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));
        }