示例#1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="configScope"></param>
        /// <param name="argumenType">The argument type</param>
        /// <param name="clrType"></param>
        /// <param name="dbType"></param>
        /// <returns></returns>
        public ITypeHandler ResolveTypeHandler(ConfigurationScope configScope, Type argumenType, string clrType, string dbType)
        {
            ITypeHandler handler = null;

            if (argumenType == null)
            {
                handler = configScope.DataExchangeFactory.TypeHandlerFactory.GetUnkownTypeHandler();
            }
            else if (typeof(IDictionary).IsAssignableFrom(argumenType))
            {
                // IDictionary
                if (clrType == null || clrType.Length == 0)
                {
                    handler = configScope.DataExchangeFactory.TypeHandlerFactory.GetUnkownTypeHandler();
                }
                else
                {
                    try
                    {
                        Type type = TypeUtils.ResolveType(clrType);
                        handler = configScope.DataExchangeFactory.TypeHandlerFactory.GetTypeHandler(type, dbType);
                    }
                    catch (Exception e)
                    {
                        //#if dotnet2
                        throw new ConfigurationErrorsException("Error. Could not set TypeHandler.  Cause: " + e.Message, e);
                        //#else
                        //						throw new ConfigurationException("Error. Could not set TypeHandler.  Cause: " + e.Message, e);
                        //#endif
                    }
                }
            }
            else if (configScope.DataExchangeFactory.TypeHandlerFactory.GetTypeHandler(argumenType, dbType) != null)
            {
                // Primitive
                handler = configScope.DataExchangeFactory.TypeHandlerFactory.GetTypeHandler(argumenType, dbType);
            }
            else
            {
                // .NET object
                if (clrType == null || clrType.Length == 0)
                {
                    handler = configScope.DataExchangeFactory.TypeHandlerFactory.GetUnkownTypeHandler();
                }
                else
                {
                    try
                    {
                        Type type = TypeUtils.ResolveType(clrType);
                        handler = configScope.DataExchangeFactory.TypeHandlerFactory.GetTypeHandler(type, dbType);
                    }
                    catch (Exception e)
                    {
                        //#if dotnet2
                        throw new ConfigurationErrorsException("Error. Could not set TypeHandler.  Cause: " + e.Message, e);
                        //#else
                        //						throw new ConfigurationException("Error. Could not set TypeHandler.  Cause: " + e.Message, e);
                        //#endif
                    }
                }
            }

            return(handler);
        }
示例#2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ParameterProperty"/> class.
        /// </summary>
        /// <param name="propertyName">Name of the property.</param>
        /// <param name="columnName">Name of the column.</param>
        /// <param name="callBackName">Name of the call back.</param>
        /// <param name="clrType">Type of the CLR.</param>
        /// <param name="dbType">Type of the db.</param>
        /// <param name="directionAttribute">The direction attribute.</param>
        /// <param name="nullValue">The null value.</param>
        /// <param name="precision">The precision.</param>
        /// <param name="scale">The scale.</param>
        /// <param name="size">The size.</param>
        /// <param name="parameterClass">The parameter class.</param>
        /// <param name="dataExchangeFactory">The data exchange factory.</param>
        public ParameterProperty(
            string propertyName,
            string columnName,
            string callBackName,
            string clrType,
            string dbType,
            string directionAttribute,
            string nullValue,
            Byte precision,
            Byte scale,
            int size,
            Type parameterClass,
            DataExchangeFactory dataExchangeFactory
            )
        {
            Contract.Require.That(propertyName, Is.Not.Null & Is.Not.Empty).When("retrieving argument propertyName in ParameterProperty constructor");

            this.columnName   = columnName;
            this.callBackName = callBackName;
            this.clrType      = clrType;
            this.dbType       = dbType;
            this.nullValue    = nullValue;
            this.precision    = precision;
            this.scale        = scale;
            this.size         = size;

            #region Direction
            if (directionAttribute.Length > 0)
            {
                direction = (ParameterDirection)Enum.Parse(typeof(ParameterDirection), directionAttribute, true);
                this.directionAttribute = direction.ToString();
            }
            #endregion

            #region Property Name
            this.propertyName = propertyName;
            if (propertyName.IndexOf('.') < 0)
            {
                isComplexMemberName = false;
            }
            else // complex member name FavouriteLineItem.Id
            {
                isComplexMemberName = true;
            }
            #endregion

            #region GetAccessor
            if (!typeof(IDictionary).IsAssignableFrom(parameterClass) && // Hashtable parameter map
                parameterClass != null && // value property
                !dataExchangeFactory.TypeHandlerFactory.IsSimpleType(parameterClass))    // value property
            {
                if (!isComplexMemberName)
                {
                    IGetAccessorFactory getAccessorFactory = dataExchangeFactory.AccessorFactory.GetAccessorFactory;
                    getAccessor = getAccessorFactory.CreateGetAccessor(parameterClass, propertyName);
                }
                else // complex member name FavouriteLineItem.Id
                {
                    string memberName = propertyName.Substring(propertyName.LastIndexOf('.') + 1);
                    string parentName = propertyName.Substring(0, propertyName.LastIndexOf('.'));
                    Type   parentType = ObjectProbe.GetMemberTypeForGetter(parameterClass, parentName);

                    IGetAccessorFactory getAccessorFactory = dataExchangeFactory.AccessorFactory.GetAccessorFactory;
                    getAccessor = getAccessorFactory.CreateGetAccessor(parentType, memberName);
                }
            }
            #endregion

            #region TypeHandler
            if (CallBackName.Length > 0)
            {
                try
                {
                    Type type = dataExchangeFactory.TypeHandlerFactory.GetType(CallBackName);
                    ITypeHandlerCallback typeHandlerCallback = (ITypeHandlerCallback)Activator.CreateInstance(type);
                    typeHandler = new CustomTypeHandler(typeHandlerCallback);
                }
                catch (Exception e)
                {
                    throw new ConfigurationException("Error occurred during custom type handler configuration.  Cause: " + e.Message, e);
                }
            }
            else
            {
                if (CLRType.Length == 0)  // Unknown
                {
                    if (getAccessor != null &&
                        dataExchangeFactory.TypeHandlerFactory.IsSimpleType(getAccessor.MemberType))
                    {
                        // Primitive
                        typeHandler = dataExchangeFactory.TypeHandlerFactory.GetTypeHandler(getAccessor.MemberType, dbType);
                    }
                    else
                    {
                        typeHandler = dataExchangeFactory.TypeHandlerFactory.GetUnkownTypeHandler();
                    }
                }
                else // If we specify a CLR type, use it
                {
                    Type type = TypeUtils.ResolveType(CLRType);

                    if (dataExchangeFactory.TypeHandlerFactory.IsSimpleType(type))
                    {
                        // Primitive
                        typeHandler = dataExchangeFactory.TypeHandlerFactory.GetTypeHandler(type, dbType);
                    }
                    else
                    {
                        // .NET object
                        type        = ObjectProbe.GetMemberTypeForGetter(parameterClass, PropertyName);
                        typeHandler = dataExchangeFactory.TypeHandlerFactory.GetTypeHandler(type, dbType);
                    }
                }
            }

            #endregion
        }
        protected IDbCommand BuildUpdateCommandForDeflatedPredicated(TypeDescriptor typeDescriptor, DataAccessObject dataAccessObject, bool valuesPredicated, bool primaryKeysPredicated, List <ObjectPropertyValue> updatedProperties, ObjectPropertyValue[] primaryKeys)
        {
            var constantPlaceholdersCount = 0;
            var assignments = new List <Expression>();
            var success     = false;

            var parameter1             = Expression.Parameter(typeDescriptor.Type);
            var requiresIdentityInsert = dataAccessObject.ToObjectInternal().HasAnyChangedPrimaryKeyServerSideProperties;

            foreach (var updated in updatedProperties)
            {
                var placeholder = updated.Value as Expression ?? new SqlConstantPlaceholderExpression(constantPlaceholdersCount++, Expression.Constant(updated.Value, updated.PropertyType.CanBeNull() ? updated.PropertyType : updated.PropertyType.MakeNullable()));

                if (placeholder.Type != updated.PropertyType)
                {
                    placeholder = Expression.Convert(placeholder, updated.PropertyType);
                }

                var m = TypeUtils.GetMethod(() => default(DataAccessObject)
                                            .SetColumnValue(default(string), default(int)))
                        .GetGenericMethodDefinition()
                        .MakeGenericMethod(typeDescriptor.Type, updated.PropertyType);

                assignments.Add(Expression.Call(null, m, parameter1, Expression.Constant(updated.PersistedName), placeholder));
            }

            var parameter = Expression.Parameter(typeDescriptor.Type);

            if (primaryKeys.Length <= 0)
            {
                throw new InvalidOperationException("Expected more than 1 primary key");
            }

            Expression where = null;

            foreach (var primaryKey in primaryKeys)
            {
                var value = primaryKey.Value;

                if (!(primaryKey.Value is Expression placeholder))
                {
                    placeholder = new SqlConstantPlaceholderExpression(constantPlaceholdersCount++, Expression.Constant(value, primaryKey.PropertyType.CanBeNull() ? primaryKey.PropertyType : primaryKey.PropertyType.MakeNullable()));
                }

                if (placeholder.Type != primaryKey.PropertyType)
                {
                    placeholder = Expression.Convert(placeholder, primaryKey.PropertyType);
                }

                var pathComponents     = primaryKey.PropertyName.Split('.');
                var propertyExpression = pathComponents.Aggregate <string, Expression>(parameter, Expression.Property);
                var currentExpression  = Expression.Equal(propertyExpression, placeholder);

                where = where == null ? currentExpression : Expression.And(where, currentExpression);
            }

            var predicate = Expression.Lambda(where, parameter);
            var method    = TypeUtils.GetMethod(() => default(IQueryable <DataAccessObject>).UpdateHelper(default(Expression <Action <DataAccessObject> >), requiresIdentityInsert))
                            .GetGenericMethodDefinition()
                            .MakeGenericMethod(typeDescriptor.Type);

            var source     = Expression.Call(null, MethodInfoFastRef.QueryableWhereMethod.MakeGenericMethod(typeDescriptor.Type), Expression.Constant(this.DataAccessModel.GetDataAccessObjects(typeDescriptor.Type)), Expression.Quote(predicate));
            var selector   = Expression.Lambda(Expression.Block(assignments), parameter1);
            var expression = (Expression)Expression.Call(null, method, source, Expression.Quote(selector), Expression.Constant(requiresIdentityInsert));

            expression = SqlQueryProvider.Bind(this.DataAccessModel, this.sqlDataTypeProvider, expression);
            expression = SqlQueryProvider.Optimize(this.DataAccessModel, expression);
            var projectionExpression = expression as SqlProjectionExpression;

            expression = projectionExpression.Select.From;

            var result = this.SqlDatabaseContext.SqlQueryFormatterManager.Format(expression);

            IDbCommand command = null;

            try
            {
                command = this.CreateCommand();

                command.CommandText = result.CommandText;

                var cachedValue = new SqlCachedUpdateInsertFormatValue {
                    formatResult = result
                };

                this.FillParameters(command, cachedValue, null, null);

                success = true;

                return(command);
            }
            finally
            {
                if (!success)
                {
                    command?.Dispose();
                }
            }
        }
示例#4
0
        public void Add(string key, object value)
        {
            if (value == null)
                return;

            //var config = CacheConfiguration.Instance.CacheConfigurations.FirstOrDefault(a => TypeUtils.GetFormattedName(a.Name).Equals(_cacheName));
            var config = _cacheConfiguration.Instance.CacheConfigurations.FirstOrDefault(a => TypeUtils.GetFormattedName(a.Name).Equals(_cacheName));

            if (config != null)
            {
                _policy.AbsoluteExpiration = DateTime.Now.AddMilliseconds(config.DefaultTimeOut);
            }
            if (_policy.AbsoluteExpiration <= DateTimeOffset.Now)
                return;
            CacheUtility.EnsureCacheKey(ref key);
            var cacheItem = new CacheItem(key, _binarySerializer.Serialize(value));

            DataCache.Add(cacheItem, _policy);

            var d = new CacheStatus(key, DateTime.Now, _policy.AbsoluteExpiration);
            CacheStatus.AddOrUpdate(key, d, (k, j) => { return d; });
        }
示例#5
0
        internal static void AddDefaultServices(IApplicationPartManager applicationPartManager, IServiceCollection services)
        {
            services.AddOptions();

            services.AddTransient <IConfigurationValidator, EndpointOptionsValidator>();

            // Options logging
            services.TryAddSingleton(typeof(IOptionFormatter <>), typeof(DefaultOptionsFormatter <>));
            services.TryAddSingleton(typeof(IOptionFormatterResolver <>), typeof(DefaultOptionsFormatterResolver <>));

            // Register system services.
            services.TryAddSingleton <ILocalSiloDetails, LocalSiloDetails>();
            services.TryAddSingleton <ISiloHost, SiloWrapper>();
            services.TryAddTransient <ILifecycleSubject, LifecycleSubject>();
            services.TryAddSingleton <SiloLifecycleSubject>();
            services.TryAddFromExisting <ISiloLifecycleSubject, SiloLifecycleSubject>();
            services.TryAddFromExisting <ISiloLifecycle, SiloLifecycleSubject>();
            services.AddSingleton <SiloOptionsLogger>();
            services.AddFromExisting <ILifecycleParticipant <ISiloLifecycle>, SiloOptionsLogger>();
            services.PostConfigure <SiloMessagingOptions>(options =>
            {
                //
                // Assign environment specific defaults post configuration if user did not configured otherwise.
                //

                if (options.SiloSenderQueues == 0)
                {
                    options.SiloSenderQueues = Environment.ProcessorCount;
                }

                if (options.GatewaySenderQueues == 0)
                {
                    options.GatewaySenderQueues = Environment.ProcessorCount;
                }
            });
            services.TryAddSingleton <TelemetryManager>();
            services.TryAddFromExisting <ITelemetryProducer, TelemetryManager>();

            services.TryAddSingleton <IAppEnvironmentStatistics, AppEnvironmentStatistics>();
            services.TryAddSingleton <IHostEnvironmentStatistics, NoOpHostEnvironmentStatistics>();
            services.TryAddSingleton <SiloStatisticsManager>();
            services.TryAddSingleton <ApplicationRequestsStatisticsGroup>();
            services.TryAddSingleton <StageAnalysisStatisticsGroup>();
            services.TryAddSingleton <SchedulerStatisticsGroup>();
            services.TryAddSingleton <SerializationStatisticsGroup>();
            services.TryAddSingleton <OverloadDetector>();

            services.TryAddSingleton <ExecutorService>();
            // queue balancer contructing related
            services.TryAddTransient <IStreamQueueBalancer, ConsistentRingQueueBalancer>();
            services.TryAddSingleton <IStreamSubscriptionHandleFactory, StreamSubscriptionHandlerFactory>();

            services.TryAddSingleton <FallbackSystemTarget>();
            services.TryAddSingleton <LifecycleSchedulingSystemTarget>();

            services.AddLogging();
            services.TryAddSingleton <ITimerRegistry, TimerRegistry>();
            services.TryAddSingleton <IReminderRegistry, ReminderRegistry>();
            services.TryAddSingleton <GrainRuntime>();
            services.TryAddSingleton <IGrainRuntime, GrainRuntime>();
            services.TryAddSingleton <IGrainCancellationTokenRuntime, GrainCancellationTokenRuntime>();
            services.TryAddSingleton <OrleansTaskScheduler>();
            services.TryAddSingleton <GrainFactory>(sp => sp.GetService <InsideRuntimeClient>().ConcreteGrainFactory);
            services.TryAddFromExisting <IGrainFactory, GrainFactory>();
            services.TryAddFromExisting <IInternalGrainFactory, GrainFactory>();
            services.TryAddFromExisting <IGrainReferenceConverter, GrainFactory>();
            services.TryAddSingleton <IGrainReferenceRuntime, GrainReferenceRuntime>();
            services.TryAddSingleton <TypeMetadataCache>();
            services.TryAddSingleton <ActivationDirectory>();
            services.TryAddSingleton <ActivationCollector>();
            services.TryAddSingleton <LocalGrainDirectory>();
            services.TryAddFromExisting <ILocalGrainDirectory, LocalGrainDirectory>();
            services.TryAddSingleton(sp => sp.GetRequiredService <LocalGrainDirectory>().GsiActivationMaintainer);
            services.TryAddSingleton <GrainTypeManager>();
            services.TryAddSingleton <MessageCenter>();
            services.TryAddFromExisting <IMessageCenter, MessageCenter>();
            services.TryAddFromExisting <ISiloMessageCenter, MessageCenter>();
            services.TryAddSingleton(FactoryUtility.Create <MessageCenter, Gateway>);
            services.AddSingleton <Gateway>(sp => sp.GetRequiredService <MessageCenter>().Gateway);
            services.TryAddSingleton <Dispatcher>(sp => sp.GetRequiredService <Catalog>().Dispatcher);
            services.TryAddSingleton <InsideRuntimeClient>();
            services.TryAddFromExisting <IRuntimeClient, InsideRuntimeClient>();
            services.TryAddFromExisting <ISiloRuntimeClient, InsideRuntimeClient>();
            services.AddFromExisting <ILifecycleParticipant <ISiloLifecycle>, InsideRuntimeClient>();
            services.TryAddSingleton <IGrainServiceFactory, GrainServiceFactory>();

            services.TryAddSingleton <IFatalErrorHandler, FatalErrorHandler>();

            services.TryAddSingleton <MultiClusterGossipChannelFactory>();
            services.TryAddSingleton <MultiClusterOracle>();
            services.TryAddSingleton <MultiClusterRegistrationStrategyManager>();
            services.TryAddFromExisting <IMultiClusterOracle, MultiClusterOracle>();
            services.TryAddSingleton <DeploymentLoadPublisher>();

            services.TryAddSingleton <IAsyncTimerFactory, AsyncTimerFactory>();
            services.TryAddSingleton <MembershipTableManager>();
            services.AddFromExisting <IHealthCheckParticipant, MembershipTableManager>();
            services.AddFromExisting <ILifecycleParticipant <ISiloLifecycle>, MembershipTableManager>();
            services.TryAddSingleton <MembershipSystemTarget>();
            services.AddFromExisting <IMembershipService, MembershipSystemTarget>();
            services.TryAddSingleton <IMembershipGossiper, MembershipGossiper>();
            services.TryAddSingleton <IRemoteSiloProber, RemoteSiloProber>();
            services.TryAddSingleton <SiloStatusOracle>();
            services.TryAddFromExisting <ISiloStatusOracle, SiloStatusOracle>();
            services.AddSingleton <ClusterHealthMonitor>();
            services.AddFromExisting <ILifecycleParticipant <ISiloLifecycle>, ClusterHealthMonitor>();
            services.AddSingleton <MembershipAgent>();
            services.AddFromExisting <ILifecycleParticipant <ISiloLifecycle>, MembershipAgent>();
            services.AddSingleton <MembershipTableCleanupAgent>();
            services.AddFromExisting <ILifecycleParticipant <ISiloLifecycle>, MembershipTableCleanupAgent>();
            services.AddSingleton <SiloStatusListenerManager>();
            services.AddFromExisting <ILifecycleParticipant <ISiloLifecycle>, SiloStatusListenerManager>();
            services.AddSingleton <ClusterMembershipService>();
            services.TryAddFromExisting <IClusterMembershipService, ClusterMembershipService>();
            services.AddFromExisting <ILifecycleParticipant <ISiloLifecycle>, ClusterMembershipService>();

            services.TryAddSingleton <ClientObserverRegistrar>();
            services.TryAddSingleton <SiloProviderRuntime>();
            services.TryAddFromExisting <IStreamProviderRuntime, SiloProviderRuntime>();
            services.TryAddFromExisting <IProviderRuntime, SiloProviderRuntime>();
            services.TryAddSingleton <ImplicitStreamSubscriberTable>();
            services.TryAddSingleton <MessageFactory>();

            services.TryAddSingleton <IGrainRegistrar <GlobalSingleInstanceRegistration>, GlobalSingleInstanceRegistrar>();
            services.TryAddSingleton <IGrainRegistrar <ClusterLocalRegistration>, ClusterLocalRegistrar>();
            services.TryAddSingleton <RegistrarManager>();
            services.TryAddSingleton <Factory <Grain, IMultiClusterRegistrationStrategy, ILogConsistencyProtocolServices> >(FactoryUtility.Create <Grain, IMultiClusterRegistrationStrategy, ProtocolServices>);
            services.TryAddSingleton(FactoryUtility.Create <GrainDirectoryPartition>);

            // Placement
            services.AddSingleton <IConfigurationValidator, ActivationCountBasedPlacementOptionsValidator>();
            services.TryAddSingleton <PlacementDirectorsManager>();
            services.TryAddSingleton <ClientObserversPlacementDirector>();

            // Configure the default placement strategy.
            services.TryAddSingleton <PlacementStrategy, RandomPlacement>();

            // Placement directors
            services.AddPlacementDirector <RandomPlacement, RandomPlacementDirector>();
            services.AddPlacementDirector <PreferLocalPlacement, PreferLocalPlacementDirector>();
            services.AddPlacementDirector <StatelessWorkerPlacement, StatelessWorkerDirector>();
            services.Replace(new ServiceDescriptor(typeof(StatelessWorkerPlacement), sp => new StatelessWorkerPlacement(), ServiceLifetime.Singleton));
            services.AddPlacementDirector <ActivationCountBasedPlacement, ActivationCountPlacementDirector>();
            services.AddPlacementDirector <HashBasedPlacement, HashBasedPlacementDirector>();

            // Activation selectors
            services.AddSingletonKeyedService <Type, IActivationSelector, RandomPlacementDirector>(typeof(RandomPlacement));
            services.AddSingletonKeyedService <Type, IActivationSelector, StatelessWorkerDirector>(typeof(StatelessWorkerPlacement));

            // Versioning
            services.TryAddSingleton <VersionSelectorManager>();
            services.TryAddSingleton <CachedVersionSelectorManager>();
            // Version selector strategy
            if (!services.Any(x => x.ServiceType == typeof(IVersionStore)))
            {
                services.TryAddSingleton <GrainVersionStore>();
                services.AddFromExisting <IVersionStore, GrainVersionStore>();
            }
            services.AddFromExisting <ILifecycleParticipant <ISiloLifecycle>, GrainVersionStore>();
            services.AddSingletonNamedService <VersionSelectorStrategy, AllCompatibleVersions>(nameof(AllCompatibleVersions));
            services.AddSingletonNamedService <VersionSelectorStrategy, LatestVersion>(nameof(LatestVersion));
            services.AddSingletonNamedService <VersionSelectorStrategy, MinimumVersion>(nameof(MinimumVersion));
            // Versions selectors
            services.AddSingletonKeyedService <Type, IVersionSelector, MinimumVersionSelector>(typeof(MinimumVersion));
            services.AddSingletonKeyedService <Type, IVersionSelector, LatestVersionSelector>(typeof(LatestVersion));
            services.AddSingletonKeyedService <Type, IVersionSelector, AllCompatibleVersionsSelector>(typeof(AllCompatibleVersions));

            // Compatibility
            services.TryAddSingleton <CompatibilityDirectorManager>();
            // Compatability strategy
            services.AddSingletonNamedService <CompatibilityStrategy, AllVersionsCompatible>(nameof(AllVersionsCompatible));
            services.AddSingletonNamedService <CompatibilityStrategy, BackwardCompatible>(nameof(BackwardCompatible));
            services.AddSingletonNamedService <CompatibilityStrategy, StrictVersionCompatible>(nameof(StrictVersionCompatible));
            // Compatability directors
            services.AddSingletonKeyedService <Type, ICompatibilityDirector, BackwardCompatilityDirector>(typeof(BackwardCompatible));
            services.AddSingletonKeyedService <Type, ICompatibilityDirector, AllVersionsCompatibilityDirector>(typeof(AllVersionsCompatible));
            services.AddSingletonKeyedService <Type, ICompatibilityDirector, StrictVersionCompatibilityDirector>(typeof(StrictVersionCompatible));

            services.TryAddSingleton <Factory <IGrainRuntime> >(sp => () => sp.GetRequiredService <IGrainRuntime>());

            // Grain activation
            services.TryAddSingleton <Catalog>();
            services.TryAddSingleton <GrainCreator>();
            services.TryAddSingleton <IGrainActivator, DefaultGrainActivator>();
            services.TryAddScoped <ActivationData.GrainActivationContextFactory>();
            services.TryAddScoped <IGrainActivationContext>(sp => sp.GetRequiredService <ActivationData.GrainActivationContextFactory>().Context);

            services.TryAddSingleton <IStreamSubscriptionManagerAdmin>(sp => new StreamSubscriptionManagerAdmin(sp.GetRequiredService <IStreamProviderRuntime>()));
            services.TryAddSingleton <IConsistentRingProvider>(
                sp =>
            {
                // TODO: make this not sux - jbragg
                var consistentRingOptions = sp.GetRequiredService <IOptions <ConsistentRingOptions> >().Value;
                var siloDetails           = sp.GetRequiredService <ILocalSiloDetails>();
                var loggerFactory         = sp.GetRequiredService <ILoggerFactory>();
                if (consistentRingOptions.UseVirtualBucketsConsistentRing)
                {
                    return(new VirtualBucketsRingProvider(siloDetails.SiloAddress, loggerFactory, consistentRingOptions.NumVirtualBucketsConsistentRing));
                }

                return(new ConsistentRingProvider(siloDetails.SiloAddress, loggerFactory));
            });

            services.TryAddSingleton(typeof(IKeyedServiceCollection <,>), typeof(KeyedServiceCollection <,>));

            // Serialization
            services.TryAddSingleton <SerializationManager>(sp => ActivatorUtilities.CreateInstance <SerializationManager>(sp,
                                                                                                                           sp.GetRequiredService <IOptions <SiloMessagingOptions> >().Value.LargeMessageWarningThreshold));
            services.TryAddSingleton <ITypeResolver, CachedTypeResolver>();
            services.TryAddSingleton <IFieldUtils, FieldUtils>();
            services.AddSingleton <BinaryFormatterSerializer>();
            services.AddSingleton <BinaryFormatterISerializableSerializer>();
            services.AddFromExisting <IKeyedSerializer, BinaryFormatterISerializableSerializer>();
#pragma warning disable CS0618 // Type or member is obsolete
            services.AddSingleton <ILBasedSerializer>();
            services.AddFromExisting <IKeyedSerializer, ILBasedSerializer>();
#pragma warning restore CS0618 // Type or member is obsolete

            // Transactions
            services.TryAddSingleton <ITransactionAgent, DisabledTransactionAgent>();

            // Application Parts
            services.TryAddSingleton <IApplicationPartManager>(applicationPartManager);
            applicationPartManager.AddApplicationPart(new AssemblyPart(typeof(RuntimeVersion).Assembly)
            {
                IsFrameworkAssembly = true
            });
            applicationPartManager.AddApplicationPart(new AssemblyPart(typeof(Silo).Assembly)
            {
                IsFrameworkAssembly = true
            });
            applicationPartManager.AddFeatureProvider(new BuiltInTypesSerializationFeaturePopulator());
            applicationPartManager.AddFeatureProvider(new AssemblyAttributeFeatureProvider <GrainInterfaceFeature>());
            applicationPartManager.AddFeatureProvider(new AssemblyAttributeFeatureProvider <GrainClassFeature>());
            applicationPartManager.AddFeatureProvider(new AssemblyAttributeFeatureProvider <SerializerFeature>());
            services.AddTransient <IConfigurationValidator, ApplicationPartValidator>();

            //Add default option formatter if none is configured, for options which are required to be configured
            services.ConfigureFormatter <SiloOptions>();
            services.ConfigureFormatter <ProcessExitHandlingOptions>();
            services.ConfigureFormatter <SchedulingOptions>();
            services.ConfigureFormatter <PerformanceTuningOptions>();
            services.ConfigureFormatter <SerializationProviderOptions>();
            services.ConfigureFormatter <ConnectionOptions>();
            services.ConfigureFormatter <SiloMessagingOptions>();
            services.ConfigureFormatter <TypeManagementOptions>();
            services.ConfigureFormatter <ClusterMembershipOptions>();
            services.ConfigureFormatter <GrainDirectoryOptions>();
            services.ConfigureFormatter <ActivationCountBasedPlacementOptions>();
            services.ConfigureFormatter <GrainCollectionOptions>();
            services.ConfigureFormatter <GrainVersioningOptions>();
            services.ConfigureFormatter <ConsistentRingOptions>();
            services.ConfigureFormatter <MultiClusterOptions>();
            services.ConfigureFormatter <StatisticsOptions>();
            services.ConfigureFormatter <TelemetryOptions>();
            services.ConfigureFormatter <LoadSheddingOptions>();
            services.ConfigureFormatter <EndpointOptions>();
            services.ConfigureFormatter <ClusterOptions>();

            // This validator needs to construct the IMembershipOracle and the IMembershipTable
            // so move it in the end so other validator are called first
            services.AddTransient <IConfigurationValidator, ClusterOptionsValidator>();
            services.AddTransient <IConfigurationValidator, SiloClusteringValidator>();
            services.AddTransient <IConfigurationValidator, DevelopmentClusterMembershipOptionsValidator>();

            // Enable hosted client.
            services.TryAddSingleton <HostedClient>();
            services.TryAddFromExisting <IHostedClient, HostedClient>();
            services.AddFromExisting <ILifecycleParticipant <ISiloLifecycle>, HostedClient>();
            services.TryAddSingleton <InvokableObjectManager>();
            services.TryAddSingleton <InternalClusterClient>();
            services.TryAddFromExisting <IInternalClusterClient, InternalClusterClient>();
            services.TryAddFromExisting <IClusterClient, InternalClusterClient>();

            // Enable collection specific Age limits
            services.AddOptions <GrainCollectionOptions>()
            .Configure <IApplicationPartManager>((options, parts) =>
            {
                var grainClasses = new GrainClassFeature();
                parts.PopulateFeature(grainClasses);

                foreach (var grainClass in grainClasses.Classes)
                {
                    var attr = grainClass.ClassType.GetCustomAttribute <CollectionAgeLimitAttribute>();
                    if (attr != null)
                    {
                        var className = TypeUtils.GetFullName(grainClass.ClassType);
                        options.ClassSpecificCollectionAge[className] = TimeSpan.FromMinutes(attr.Minutes);
                    }
                }
            });

            // Validate all CollectionAgeLimit values for the right configuration.
            services.AddTransient <IConfigurationValidator, GrainCollectionOptionsValidator>();

            services.AddTransient <IConfigurationValidator, LoadSheddingValidator>();

            services.TryAddSingleton <ITimerManager, TimerManagerImpl>();

            // persistent state facet support
            services.TryAddSingleton <IPersistentStateFactory, PersistentStateFactory>();
            services.TryAddSingleton(typeof(IAttributeToFactoryMapper <PersistentStateAttribute>), typeof(PersistentStateAttributeMapper));

            // Networking
            services.TryAddSingleton <ConnectionManager>();
            services.AddSingleton <ILifecycleParticipant <ISiloLifecycle>, ConnectionManagerLifecycleAdapter <ISiloLifecycle> >();
            services.AddSingleton <ILifecycleParticipant <ISiloLifecycle>, SiloConnectionMaintainer>();
            services.TryAddSingleton <IConnectionFactory, SocketConnectionFactory>();
            services.TryAddSingleton <IConnectionListenerFactory, SocketConnectionListenerFactory>();
            services.TryAddTransient <IMessageSerializer>(sp => ActivatorUtilities.CreateInstance <MessageSerializer>(sp,
                                                                                                                      sp.GetRequiredService <IOptions <SiloMessagingOptions> >().Value.MaxMessageHeaderSize,
                                                                                                                      sp.GetRequiredService <IOptions <SiloMessagingOptions> >().Value.MaxMessageBodySize));
            services.TryAddSingleton <ConnectionFactory, SiloConnectionFactory>();
            services.TryAddSingleton <INetworkingTrace, NetworkingTrace>();

            // Use Orleans server.
            services.AddSingleton <ILifecycleParticipant <ISiloLifecycle>, SiloConnectionListener>();
            services.AddSingleton <ILifecycleParticipant <ISiloLifecycle>, GatewayConnectionListener>();
            services.AddSingleton <SocketSchedulers>();
            services.AddSingleton <SharedMemoryPool>();
        }
示例#6
0
        /// <summary>
        /// Initialize the PropertyInfo of the result property.
        /// </summary>
        /// <param name="resultClass"></param>
        /// <param name="configScope"></param>
        public void Initialize(ConfigurationScope configScope, Type resultClass)
        {
            if (_propertyName.Length > 0 &&
                _propertyName != "value" &&
                !typeof(IDictionary).IsAssignableFrom(resultClass))
            {
                if (!_isComplexMemberName)
                {
                    _setAccessor = configScope.DataExchangeFactory.AccessorFactory.SetAccessorFactory.CreateSetAccessor(resultClass, _propertyName);
                }
                else                 // complex member name FavouriteLineItem.Id
                {
                    MemberInfo propertyInfo = ObjectProbe.GetMemberInfoForSetter(resultClass, _propertyName);
                    string     memberName   = _propertyName.Substring(_propertyName.LastIndexOf('.') + 1);
                    _setAccessor = configScope.DataExchangeFactory.AccessorFactory.SetAccessorFactory.CreateSetAccessor(propertyInfo.ReflectedType, memberName);
                }

#if dotnet2
                _isGenericIList = TypeUtils.IsImplementGenericIListInterface(MemberType);
#endif
                _isIList = typeof(IList).IsAssignableFrom(MemberType);

                // set the list factory
#if dotnet2
                if (_isGenericIList)
                {
                    if (MemberType.IsArray)
                    {
                        _listFactory = _arrayListFactory;
                    }
                    else
                    {
                        Type[] typeArgs = MemberType.GetGenericArguments();

                        if (typeArgs.Length == 0)// Custom collection which derive from List<T>
                        {
                            _listFactory = configScope.DataExchangeFactory.ObjectFactory.CreateFactory(MemberType, Type.EmptyTypes);
                        }
                        else
                        {
                            Type genericIList      = typeof(IList <>);
                            Type interfaceListType = genericIList.MakeGenericType(typeArgs);

                            Type genericList = typeof(List <>);
                            Type listType    = genericList.MakeGenericType(typeArgs);

                            if ((interfaceListType == MemberType) || (listType == MemberType))
                            {
                                Type constructedType = genericList.MakeGenericType(typeArgs);
                                _listFactory = configScope.DataExchangeFactory.ObjectFactory.CreateFactory(
                                    constructedType,
                                    Type.EmptyTypes);
                            }
                            else // Custom collection which derive from List<T>
                            {
                                _listFactory = configScope.DataExchangeFactory.ObjectFactory.CreateFactory(MemberType, Type.EmptyTypes);
                            }
                        }
                    }
                }
                else
#endif
                if (_isIList)
                {
                    if (MemberType.IsArray)
                    {
                        _listFactory = _arrayListFactory;
                    }
                    else
                    {
                        if (MemberType == typeof(IList))
                        {
                            _listFactory = _arrayListFactory;
                        }
                        else // custom collection
                        {
                            _listFactory = configScope.DataExchangeFactory.ObjectFactory.CreateFactory(MemberType, Type.EmptyTypes);
                        }
                    }
                }
            }

            if (CallBackName != null && CallBackName.Length > 0)
            {
                configScope.ErrorContext.MoreInfo = "Result property '" + _propertyName + "' check the typeHandler attribute '" + CallBackName + "' (must be a ITypeHandlerCallback implementation).";
                try
                {
                    Type type = configScope.SqlMapper.TypeHandlerFactory.GetType(CallBackName);
                    ITypeHandlerCallback typeHandlerCallback = (ITypeHandlerCallback)Activator.CreateInstance(type);
                    _typeHandler = new CustomTypeHandler(typeHandlerCallback);
                }
                catch (Exception e)
                {
                    throw new ConfigurationException("Error occurred during custom type handler configuration.  Cause: " + e.Message, e);
                }
            }
            else
            {
                configScope.ErrorContext.MoreInfo = "Result property '" + _propertyName + "' set the typeHandler attribute.";
                _typeHandler = configScope.ResolveTypeHandler(resultClass, _propertyName, _clrType, _dbType, true);
            }

            if (IsLazyLoad)
            {
                _lazyFactory = new LazyFactoryBuilder().GetLazyFactory(_setAccessor.MemberType);
            }
        }
示例#7
0
        /// <summary>
        /// Gets text to be used as a member value
        /// </summary>
        /// <param name="memberInfo"></param>
        /// <returns>The text to be used as a member value. Null if the member has no value or value cannot be determined.</returns>
        public string GetMemberValueText(MemberInfo memberInfo)
        {
            if (memberInfo.DeclaringType == null)
            {
                return(null);
            }

            try
            {
                object instance      = memberInfo.IsStatic() ? null : ActivatorUtils.CreateInstanceAutoFillGenericParameters(memberInfo.DeclaringType);
                var    valueObj      = new object();
                object valueObjGuard = valueObj;

                switch (memberInfo)
                {
                case FieldInfo fieldInfo:
                    valueObj = fieldInfo.GetValue(instance);
                    break;

                case PropertyInfo propertyInfo:
                    valueObj = propertyInfo.GetValue(instance);
                    break;
                }

                // if valueObj hasn't been assigned in the switch
                if (valueObj == valueObjGuard)
                {
                    return(null);
                }

                // if valueObj's value is the default value for its type
                if (valueObj == null || valueObj.Equals(TypeUtils.GetDefaultValue(valueObj.GetType())))
                {
                    return(null);
                }

                string memberType = _typeService.GetTsTypeName(memberInfo).GetTsTypeUnion(0);
                string quote      = GeneratorOptions.SingleQuotes ? "'" : "\"";

                switch (valueObj)
                {
                case Guid valueGuid when memberType == "string":
                    return(quote + valueGuid + quote);

                case DateTime valueDateTime when memberType == "Date":
                    return($@"new Date({quote}{valueDateTime}{quote})");

                case DateTime valueDateTime when memberType == "string":
                    return(quote + valueDateTime + quote);

                case DateTimeOffset valueDateTimeOffset when memberType == "Date":
                    return($@"new Date({quote}{valueDateTimeOffset}{quote})");

                case DateTimeOffset valueDateTimeOffset when memberType == "string":
                    return(quote + valueDateTimeOffset + quote);

                default:
                    return(JsonConvert.SerializeObject(valueObj).Replace("\"", quote));
                }
            }
            catch (MissingMethodException e)
            {
                _logger?.Log($"Cannot determine the default value for member '{memberInfo.DeclaringType.FullName}.{memberInfo.Name}', because type '{memberInfo.DeclaringType.FullName}' has no default constructor.", LogLevel.Debug);
            }
            catch (ArgumentException e) when(e.InnerException is TypeLoadException)
            {
                _logger?.Log($"Cannot determine the default value for member '{memberInfo.DeclaringType.FullName}.{memberInfo.Name}', because type '{memberInfo.DeclaringType.FullName}' has generic parameters with base class or interface constraints.", LogLevel.Debug);
            }
            catch (Exception e)
            {
                _logger?.Log($"Cannot determine the default value for member '{memberInfo.DeclaringType.FullName}.{memberInfo.Name}', because an unknown exception occurred: '{e.Message}'", LogLevel.Debug);
            }

            return(null);
        }
示例#8
0
        /// <inheritdoc />
        public override void Initialize(LayoutElementsContainer layout)
        {
            if (!HasDifferentTypes)
            {
                _type = Values.Type.Type != typeof(object) || Values[0] == null ? Values.Type : TypeUtils.GetObjectType(Values[0]);

                float height         = 48;
                var   attributes     = Values.GetAttributes();
                var   assetReference = (AssetReferenceAttribute)attributes?.FirstOrDefault(x => x is AssetReferenceAttribute);
                if (assetReference != null)
                {
                    if (assetReference.UseSmallPicker)
                    {
                        height = 32;
                    }

                    if (!string.IsNullOrEmpty(assetReference.TypeName))
                    {
                        var customType = TypeUtils.GetType(assetReference.TypeName);
                        if (customType != ScriptType.Null)
                        {
                            _type = customType;
                        }
                        else
                        {
                            Debug.LogWarning(string.Format("Unknown asset type '{0}' to use for asset picker filter.", assetReference.TypeName));
                        }
                    }
                }

                _element = layout.Custom <AssetPicker>();
                _element.CustomControl.AssetType            = _type;
                _element.CustomControl.Height               = height;
                _element.CustomControl.SelectedItemChanged += OnSelectedItemChanged;
            }
        }
 public Type TypeFromCode(string code) => Type.GetType(code) ?? TypeUtils.GetType(code);
        public IPayee FindPayee(string ofType, int Id)
        {
            Type type = TypeUtils.GetType(ofType);

            return(ObjectFinder.Instances <IPayee>(type).SingleOrDefault(p => p.Id == Id));
        }
示例#11
0
        private void RegisterProviderType(Type t)
        {
            // First, figure out the provider type name
            var            typeName = TypeUtils.GetFullName(t);
            IList <String> providerNames;

            lock (providers)
            {
                providerNames = providers.Keys.ToList();
            }

            // Now see if we have any config entries for that type
            // If there's no config entry, then we don't load the type
            Type[] constructorBindingTypes = new[] { typeof(string), typeof(XmlElement) };
            foreach (var entry in providerConfigs.Values)
            {
                var fullConfig = (ProviderConfiguration)entry;

                // Check if provider is already initialized. Skip loading it if so.
                if (providerNames.Contains(fullConfig.Name))
                {
                    continue;
                }

                if (fullConfig.Type != typeName)
                {
                    continue;
                }

                // Found one! Now look for an appropriate constructor; try TProvider(string, Dictionary<string,string>) first
                var constructor = TypeUtils.GetConstructorThatMatches(t, constructorBindingTypes);
                var parms       = new object[] { typeName, entry.Properties };

                if (constructor == null)
                {
                    // See if there's a default constructor to use, if there's no two-parameter constructor
                    constructor = TypeUtils.GetConstructorThatMatches(t, Type.EmptyTypes);
                    parms       = new object[0];
                }
                if (constructor == null)
                {
                    logger.Warn(ErrorCode.Provider_InstanceConstructionError1, $"Accessible constructor does not exist for type {t.Name}");

                    continue;
                }

                TProvider instance;
                try
                {
                    instance = (TProvider)constructor.Invoke(parms);
                }
                catch (Exception ex)
                {
                    logger.Warn(ErrorCode.Provider_InstanceConstructionError1, "Error constructing an instance of a " + typeName +
                                " provider using type " + t.Name + " for provider with name " + fullConfig.Name, ex);
                    return;
                }

                lock (providers)
                {
                    providers[fullConfig.Name] = instance;
                }

                logger.Info(ErrorCode.Provider_Loaded, "Loaded provider of type {0} Name={1}", typeName, fullConfig.Name);
            }
        }
        public IList <IPayee> Payees(string ofType)
        {
            Type type = TypeUtils.GetType(ofType);

            return(ObjectFinder.Instances <IPayee>(type).ToList());
        }
示例#13
0
            /// <inheritdoc />
            public override void OnLoaded()
            {
                base.OnLoaded();

                // Update title and the tooltip
                var typeName = (string)Values[0];

                TooltipText = typeName;
                var type = TypeUtils.GetType(typeName);

                if (type)
                {
                    GetBox(0).CurrentType = type;
                    Title = (_isUnpacking ? "Unpack " : "Pack ") + type.Name;
                    var attributes       = type.GetAttributes(false);
                    var tooltipAttribute = (TooltipAttribute)attributes.FirstOrDefault(x => x is TooltipAttribute);
                    if (tooltipAttribute != null)
                    {
                        TooltipText += "\n" + tooltipAttribute.Text;
                    }
                }
                else
                {
                    Title = (_isUnpacking ? "Unpack " : "Pack ") + typeName;
                }

                // Update the boxes
                int fieldsLength;

                if (type)
                {
                    // Generate boxes for all structure fields
                    var fields = type.GetMembers(BindingFlags.Public | BindingFlags.Instance).Where(x => x.IsField).ToArray();
                    fieldsLength = fields.Length;
                    for (var i = 0; i < fieldsLength; i++)
                    {
                        var field = fields[i];
                        MakeBox(i + 1, field.Name, field.ValueType);
                    }

                    // Remove any not used boxes
                    for (int i = fieldsLength + 2; i < 32; i++)
                    {
                        var box = GetBox(i);
                        if (box == null)
                        {
                            break;
                        }
                        RemoveElement(box);
                    }

                    // Save structure layout
                    if (fieldsLength == 0)
                    {
                        // Skip allocations if structure is empty
                        Values[1] = Utils.GetEmptyArray <byte>();
                    }
                    else
                    {
                        using (var stream = new MemoryStream())
                            using (var writer = new BinaryWriter(stream))
                            {
                                writer.Write((byte)1);      // Version
                                writer.Write(fieldsLength); // Fields count
                                for (int i = 0; i < fieldsLength; i++)
                                {
                                    Utilities.Utils.WriteStr(writer, fields[i].Name, 11);          // Field type
                                    Utilities.Utils.WriteVariantType(writer, fields[i].ValueType); // Field type
                                }
                                Values[1] = stream.ToArray();
                            }
                    }
                }
                else if (Values[1] is byte[] data && data.Length != 0 && data[0] == 1)
                {
                    // Recreate node boxes based on the saved structure layout to preserve the connections
                    using (var stream = new MemoryStream(data))
                        using (var reader = new BinaryReader(stream))
                        {
                            reader.ReadByte();                 // Version
                            fieldsLength = reader.ReadInt32(); // Fields count
                            for (int i = 0; i < fieldsLength; i++)
                            {
                                var fieldName = Utilities.Utils.ReadStr(reader, 11);     // Field name
                                var fieldType = Utilities.Utils.ReadVariantType(reader); // Field type
                                MakeBox(i + 1, fieldName, new ScriptType(fieldType));
                            }
                        }
                }

                // Update node size
                ResizeAuto();
            }
示例#14
0
        private ITypeSpecBuilder CreateSpecification(Type type)
        {
            TypeUtils.GetType(type.FullName); // This should ensure type is cached

            return(IsService(type) ? (ITypeSpecBuilder)ImmutableSpecFactory.CreateServiceSpecImmutable(type, metamodel) : ImmutableSpecFactory.CreateObjectSpecImmutable(type, metamodel));
        }
示例#15
0
        /// <summary>
        /// Adds serialization type descriptions from <paramref name="targetAssembly"/> to <paramref name="serializationTypes"/>.
        /// </summary>
        /// <param name="serializationTypes">The serialization type descriptions.</param>
        /// <param name="targetAssembly">The target assembly for generated code.</param>
        /// <param name="assemblies"></param>
        private void AddSerializationTypes(SerializationTypeDescriptions serializationTypes, Assembly targetAssembly, List <Assembly> assemblies)
        {
            // Only types which exist in assemblies referenced by the target assembly can be referenced.
            var references = new HashSet <string>(
                assemblies.SelectMany(asm =>
                                      asm.GetReferencedAssemblies()
                                      .Select(referenced => referenced.Name)
                                      .Concat(new[] { asm.GetName().Name })));

            bool IsAssemblyReferenced(Type type)
            {
                // If the target doesn't reference this type's assembly, it cannot reference a type within that assembly.
                return(references.Contains(type.Assembly.GetName().Name));
            }

            // Visit all types in other assemblies for serialization metadata.
            foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                if (!references.Contains(assembly.GetName().Name))
                {
                    continue;
                }
                foreach (var type in TypeUtils.GetDefinedTypes(assembly, this.logger))
                {
                    this.typeCollector.RecordEncounteredType(type);
                }
            }

            // Returns true if a type can be accessed from source and false otherwise.
            bool IsAccessibleType(Type type) => TypeUtilities.IsAccessibleFromAssembly(type, targetAssembly);

            foreach (var type in this.typeCollector.EncounteredTypes)
            {
                // Skip types which can not or should not be referenced.
                if (type.IsGenericParameter)
                {
                    continue;
                }
                if (!IsAssemblyReferenced(type))
                {
                    continue;
                }
                if (type.IsNestedPrivate)
                {
                    continue;
                }
                if (type.GetCustomAttribute <CompilerGeneratedAttribute>() != null)
                {
                    continue;
                }
                if (IsOrleansGeneratedCode(type))
                {
                    continue;
                }

                var qualifiedTypeName = RuntimeTypeNameFormatter.Format(type);
                if (this.knownTypes.Contains(qualifiedTypeName))
                {
                    continue;
                }

                var typeKeyString = type.OrleansTypeKeyString();
                serializationTypes.KnownTypes.Add(new KnownTypeDescription
                {
                    Type    = qualifiedTypeName,
                    TypeKey = typeKeyString
                });

                if (this.logger.IsEnabled(LogLevel.Debug))
                {
                    this.logger.Debug(
                        "Found type {0} with type key \"{1}\"",
                        type.GetParseableName(),
                        typeKeyString);
                }

                if (!IsAccessibleType(type))
                {
                    continue;
                }

                var typeSyntax           = type.GetTypeSyntax(includeGenericParameters: false);
                var serializerAttributes = type.GetCustomAttributes <SerializerAttribute>().ToList();
                if (serializerAttributes.Count > 0)
                {
                    // Account for serializer types.
                    foreach (var serializerAttribute in serializerAttributes)
                    {
                        if (!IsAccessibleType(serializerAttribute.TargetType))
                        {
                            continue;
                        }

                        if (this.logger.IsEnabled(LogLevel.Information))
                        {
                            this.logger.Info(
                                "Found type {0} is a serializer for type {1}",
                                type.GetParseableName(),
                                serializerAttribute.TargetType.GetParseableName());
                        }

                        serializationTypes.SerializerTypes.Add(
                            new SerializerTypeDescription
                        {
                            Serializer = typeSyntax,
                            Target     = serializerAttribute.TargetType.GetTypeSyntax(includeGenericParameters: false)
                        });
                    }
                }
                else
                {
                    // Account for self-serializing types.
                    SerializationManager.GetSerializationMethods(type, out var copier, out var serializer, out var deserializer);
                    if (copier != null || serializer != null || deserializer != null)
                    {
                        if (this.logger.IsEnabled(LogLevel.Information))
                        {
                            this.logger.Info(
                                "Found type {0} is self-serializing.",
                                type.GetParseableName());
                        }

                        serializationTypes.SerializerTypes.Add(
                            new SerializerTypeDescription
                        {
                            Serializer = typeSyntax,
                            Target     = typeSyntax
                        });
                    }
                }
            }
        }
 public Type TypeFromCode(string code)
 {
     return(Type.GetType(code) ?? TypeUtils.GetType(code));
 }
示例#17
0
 /// <summary>
 /// Creates a <see cref="LabelTarget"/> representing a label with the given type and name.
 /// </summary>
 /// <param name="type">The type of value that is passed when jumping to the label.</param>
 /// <param name="name">The name of the label.</param>
 /// <returns>The new <see cref="LabelTarget"/>.</returns>
 public static LabelTarget Label(Type type, string?name)
 {
     ContractUtils.RequiresNotNull(type, nameof(type));
     TypeUtils.ValidateType(type, nameof(type));
     return(new LabelTarget(type, name));
 }
示例#18
0
        /// <inheritdoc />
        public override void Initialize(LayoutElementsContainer layout)
        {
            _readOnly        = false;
            _canReorderItems = true;
            _notNullItems    = false;

            // No support for different collections for now
            if (HasDifferentValues || HasDifferentTypes)
            {
                return;
            }

            var size = Count;

            // Try get CollectionAttribute for collection editor meta
            var   attributes         = Values.GetAttributes();
            Type  overrideEditorType = null;
            float spacing            = 10.0f;
            var   collection         = (CollectionAttribute)attributes?.FirstOrDefault(x => x is CollectionAttribute);

            if (collection != null)
            {
                // TODO: handle NotNullItems by filtering child editors SetValue

                _readOnly          = collection.ReadOnly;
                _canReorderItems   = collection.CanReorderItems;
                _notNullItems      = collection.NotNullItems;
                overrideEditorType = TypeUtils.GetType(collection.OverrideEditorTypeName).Type;
                spacing            = collection.Spacing;
            }

            // Size
            if (_readOnly)
            {
                layout.Label("Size", size.ToString());
            }
            else
            {
                _size = layout.IntegerValue("Size");
                _size.IntValue.MinValue      = 0;
                _size.IntValue.MaxValue      = ushort.MaxValue;
                _size.IntValue.Value         = size;
                _size.IntValue.ValueChanged += OnSizeChanged;
            }

            // Elements
            if (size > 0)
            {
                var elementType = ElementType;
                if (_canReorderItems)
                {
                    for (int i = 0; i < size; i++)
                    {
                        if (i != 0 && spacing > 0f)
                        {
                            if (layout.Children.Count > 0 && layout.Children[layout.Children.Count - 1] is PropertiesListElement propertiesListElement)
                            {
                                if (propertiesListElement.Labels.Count > 0)
                                {
                                    var label  = propertiesListElement.Labels[propertiesListElement.Labels.Count - 1];
                                    var margin = label.Margin;
                                    margin.Bottom += spacing;
                                    label.Margin   = margin;
                                }
                                propertiesListElement.Space(spacing);
                            }
                            else
                            {
                                layout.Space(spacing);
                            }
                        }

                        var overrideEditor = overrideEditorType != null ? (CustomEditor)Activator.CreateInstance(overrideEditorType) : null;
                        layout.Object(new CollectionItemLabel(this, i), new ListValueContainer(elementType, i, Values), overrideEditor);
                    }
                }
                else
                {
                    for (int i = 0; i < size; i++)
                    {
                        if (i != 0 && spacing > 0f)
                        {
                            if (layout.Children.Count > 0 && layout.Children[layout.Children.Count - 1] is PropertiesListElement propertiesListElement)
                            {
                                propertiesListElement.Space(spacing);
                            }
                            else
                            {
                                layout.Space(spacing);
                            }
                        }

                        var overrideEditor = overrideEditorType != null ? (CustomEditor)Activator.CreateInstance(overrideEditorType) : null;
                        layout.Object("Element " + i, new ListValueContainer(elementType, i, Values), overrideEditor);
                    }
                }
            }
            _elementsCount = size;

            // Add/Remove buttons
            if (!_readOnly)
            {
                var area      = layout.Space(20);
                var addButton = new Button(area.ContainerControl.Width - (16 + 16 + 2 + 2), 2, 16, 16)
                {
                    Text         = "+",
                    TooltipText  = "Add new item",
                    AnchorPreset = AnchorPresets.TopRight,
                    Parent       = area.ContainerControl
                };
                addButton.Clicked += () =>
                {
                    if (IsSetBlocked)
                    {
                        return;
                    }

                    Resize(Count + 1);
                };
                var removeButton = new Button(addButton.Right + 2, addButton.Y, 16, 16)
                {
                    Text         = "-",
                    TooltipText  = "Remove last item",
                    AnchorPreset = AnchorPresets.TopRight,
                    Parent       = area.ContainerControl,
                    Enabled      = size > 0
                };
                removeButton.Clicked += () =>
                {
                    if (IsSetBlocked)
                    {
                        return;
                    }

                    Resize(Count - 1);
                };
            }
        }
        private void EmitNullableCoalesce(BinaryExpression b)
        {
            Debug.Assert(b.Method == null);

            LocalBuilder loc       = GetLocal(b.Left.Type);
            Label        labIfNull = _ilg.DefineLabel();
            Label        labEnd    = _ilg.DefineLabel();

            EmitExpression(b.Left);
            _ilg.Emit(OpCodes.Stloc, loc);
            _ilg.Emit(OpCodes.Ldloca, loc);
            _ilg.EmitHasValue(b.Left.Type);
            _ilg.Emit(OpCodes.Brfalse, labIfNull);

            Type nnLeftType = b.Left.Type.GetNonNullableType();

            if (b.Conversion != null)
            {
                Debug.Assert(b.Conversion.ParameterCount == 1);
                ParameterExpression p = b.Conversion.GetParameter(0);
                Debug.Assert(p.Type.IsAssignableFrom(b.Left.Type) ||
                             p.Type.IsAssignableFrom(nnLeftType));

                // emit the delegate instance
                EmitLambdaExpression(b.Conversion);

                // emit argument
                if (!p.Type.IsAssignableFrom(b.Left.Type))
                {
                    _ilg.Emit(OpCodes.Ldloca, loc);
                    _ilg.EmitGetValueOrDefault(b.Left.Type);
                }
                else
                {
                    _ilg.Emit(OpCodes.Ldloc, loc);
                }

                // emit call to invoke
                _ilg.Emit(OpCodes.Callvirt, b.Conversion.Type.GetInvokeMethod());
            }
            else if (TypeUtils.AreEquivalent(b.Type, b.Left.Type))
            {
                _ilg.Emit(OpCodes.Ldloc, loc);
            }
            else
            {
                _ilg.Emit(OpCodes.Ldloca, loc);
                _ilg.EmitGetValueOrDefault(b.Left.Type);
                if (!TypeUtils.AreEquivalent(b.Type, nnLeftType))
                {
                    _ilg.EmitConvertToType(nnLeftType, b.Type, isChecked: true, locals: this);
                }
            }

            FreeLocal(loc);

            _ilg.Emit(OpCodes.Br, labEnd);
            _ilg.MarkLabel(labIfNull);
            EmitExpression(b.Right);
            if (!TypeUtils.AreEquivalent(b.Right.Type, b.Type))
            {
                _ilg.EmitConvertToType(b.Right.Type, b.Type, isChecked: true, locals: this);
            }
            _ilg.MarkLabel(labEnd);
        }
示例#20
0
        internal static Type ReadVariantType(this BinaryReader stream)
        {
            var variantType    = (VariantType)stream.ReadByte();
            var typeNameLength = stream.ReadInt32();

            if (typeNameLength == int.MaxValue)
            {
                typeNameLength = stream.ReadInt32();
                var data = new byte[typeNameLength];
                for (int i = 0; i < typeNameLength; i++)
                {
                    var c = stream.ReadByte();
                    data[i] = (byte)(c ^ 77);
                }
                var typeName = System.Text.Encoding.ASCII.GetString(data);
                return(TypeUtils.GetManagedType(typeName));
            }
            if (typeNameLength > 0)
            {
                // [Deprecated on 27.08.2020, expires on 27.08.2021]
                var data = new char[typeNameLength];
                for (int i = 0; i < typeNameLength; i++)
                {
                    var c = stream.ReadUInt16();
                    data[i] = (char)(c ^ 77);
                }
                var typeName = new string(data);
                return(TypeUtils.GetManagedType(typeName));
            }
            switch (variantType)
            {
            case VariantType.Null: return(null);

            case VariantType.Void: return(typeof(void));

            case VariantType.Bool: return(typeof(bool));

            case VariantType.Int16: return(typeof(short));

            case VariantType.Uint16: return(typeof(ushort));

            case VariantType.Int: return(typeof(int));

            case VariantType.Uint: return(typeof(uint));

            case VariantType.Int64: return(typeof(long));

            case VariantType.Uint64: return(typeof(ulong));

            case VariantType.Float: return(typeof(float));

            case VariantType.Double: return(typeof(double));

            case VariantType.Pointer: return(typeof(IntPtr));

            case VariantType.String: return(typeof(string));

            case VariantType.Typename: return(typeof(Type));

            case VariantType.Object: return(typeof(FlaxEngine.Object));

            case VariantType.Asset: return(typeof(Asset));

            case VariantType.Vector2: return(typeof(Vector2));

            case VariantType.Vector3: return(typeof(Vector3));

            case VariantType.Vector4: return(typeof(Vector4));

            case VariantType.Int2: return(typeof(Int2));

            case VariantType.Int3: return(typeof(Int3));

            case VariantType.Int4: return(typeof(Int4));

            case VariantType.Color: return(typeof(Color));

            case VariantType.Guid: return(typeof(Guid));

            case VariantType.BoundingBox: return(typeof(BoundingBox));

            case VariantType.BoundingSphere: return(typeof(BoundingSphere));

            case VariantType.Quaternion: return(typeof(Quaternion));

            case VariantType.Transform: return(typeof(Transform));

            case VariantType.Rectangle: return(typeof(Rectangle));

            case VariantType.Ray: return(typeof(Ray));

            case VariantType.Matrix: return(typeof(Matrix));

            case VariantType.Array: return(typeof(object[]));

            case VariantType.Dictionary: return(typeof(Dictionary <object, object>));

            case VariantType.ManagedObject: return(typeof(object));

            case VariantType.Blob: return(typeof(byte[]));

            default: throw new ArgumentOutOfRangeException($"Unknown Variant Type {variantType} without typename.");
            }
        }
示例#21
0
        private static void EmitNumericConversion(this ILGenerator il, Type typeFrom, Type typeTo, bool isChecked)
        {
            bool isFromUnsigned      = TypeUtils.IsUnsigned(typeFrom);
            bool isFromFloatingPoint = TypeUtils.IsFloatingPoint(typeFrom);

            if (typeTo == typeof(Single))
            {
                if (isFromUnsigned)
                {
                    il.Emit(OpCodes.Conv_R_Un);
                }
                il.Emit(OpCodes.Conv_R4);
            }
            else if (typeTo == typeof(Double))
            {
                if (isFromUnsigned)
                {
                    il.Emit(OpCodes.Conv_R_Un);
                }
                il.Emit(OpCodes.Conv_R8);
            }
            else
            {
                TypeCode tc = typeTo.GetTypeCode();
                if (isChecked)
                {
                    // Overflow checking needs to know if the source value on the IL stack is unsigned or not.
                    if (isFromUnsigned)
                    {
                        switch (tc)
                        {
                        case TypeCode.SByte:
                            il.Emit(OpCodes.Conv_Ovf_I1_Un);
                            break;

                        case TypeCode.Int16:
                            il.Emit(OpCodes.Conv_Ovf_I2_Un);
                            break;

                        case TypeCode.Int32:
                            il.Emit(OpCodes.Conv_Ovf_I4_Un);
                            break;

                        case TypeCode.Int64:
                            il.Emit(OpCodes.Conv_Ovf_I8_Un);
                            break;

                        case TypeCode.Byte:
                            il.Emit(OpCodes.Conv_Ovf_U1_Un);
                            break;

                        case TypeCode.UInt16:
                        case TypeCode.Char:
                            il.Emit(OpCodes.Conv_Ovf_U2_Un);
                            break;

                        case TypeCode.UInt32:
                            il.Emit(OpCodes.Conv_Ovf_U4_Un);
                            break;

                        case TypeCode.UInt64:
                            il.Emit(OpCodes.Conv_Ovf_U8_Un);
                            break;

                        default:
                            throw Error.UnhandledConvert(typeTo);
                        }
                    }
                    else
                    {
                        switch (tc)
                        {
                        case TypeCode.SByte:
                            il.Emit(OpCodes.Conv_Ovf_I1);
                            break;

                        case TypeCode.Int16:
                            il.Emit(OpCodes.Conv_Ovf_I2);
                            break;

                        case TypeCode.Int32:
                            il.Emit(OpCodes.Conv_Ovf_I4);
                            break;

                        case TypeCode.Int64:
                            il.Emit(OpCodes.Conv_Ovf_I8);
                            break;

                        case TypeCode.Byte:
                            il.Emit(OpCodes.Conv_Ovf_U1);
                            break;

                        case TypeCode.UInt16:
                        case TypeCode.Char:
                            il.Emit(OpCodes.Conv_Ovf_U2);
                            break;

                        case TypeCode.UInt32:
                            il.Emit(OpCodes.Conv_Ovf_U4);
                            break;

                        case TypeCode.UInt64:
                            il.Emit(OpCodes.Conv_Ovf_U8);
                            break;

                        default:
                            throw Error.UnhandledConvert(typeTo);
                        }
                    }
                }
                else
                {
                    switch (tc)
                    {
                    case TypeCode.SByte:
                        il.Emit(OpCodes.Conv_I1);
                        break;

                    case TypeCode.Byte:
                        il.Emit(OpCodes.Conv_U1);
                        break;

                    case TypeCode.Int16:
                        il.Emit(OpCodes.Conv_I2);
                        break;

                    case TypeCode.UInt16:
                    case TypeCode.Char:
                        il.Emit(OpCodes.Conv_U2);
                        break;

                    case TypeCode.Int32:
                        il.Emit(OpCodes.Conv_I4);
                        break;

                    case TypeCode.UInt32:
                        il.Emit(OpCodes.Conv_U4);
                        break;

                    case TypeCode.Int64:
                        if (isFromUnsigned)
                        {
                            il.Emit(OpCodes.Conv_U8);
                        }
                        else
                        {
                            il.Emit(OpCodes.Conv_I8);
                        }
                        break;

                    case TypeCode.UInt64:
                        if (isFromUnsigned || isFromFloatingPoint)
                        {
                            il.Emit(OpCodes.Conv_U8);
                        }
                        else
                        {
                            il.Emit(OpCodes.Conv_I8);
                        }
                        break;

                    default:
                        throw Error.UnhandledConvert(typeTo);
                    }
                }
            }
        }
示例#22
0
        internal static unsafe object ReadVariant(this BinaryReader stream)
        {
            Type   type           = null;
            var    variantType    = (VariantType)stream.ReadByte();
            var    typeNameLength = stream.ReadInt32();
            string typeName       = string.Empty;

            if (typeNameLength == int.MaxValue)
            {
                typeNameLength = stream.ReadInt32();
                var data = new byte[typeNameLength];
                for (int i = 0; i < typeNameLength; i++)
                {
                    var c = stream.ReadByte();
                    data[i] = (byte)(c ^ 77);
                }
                typeName = System.Text.Encoding.ASCII.GetString(data);
                type     = TypeUtils.GetManagedType(typeName);
            }
            else if (typeNameLength > 0)
            {
                // [Deprecated on 27.08.2020, expires on 27.08.2021]
                var data = new char[typeNameLength];
                for (int i = 0; i < typeNameLength; i++)
                {
                    var c = stream.ReadUInt16();
                    data[i] = (char)(c ^ 77);
                }
                typeName = new string(data);
                type     = TypeUtils.GetManagedType(typeName);
            }
            switch (variantType)
            {
            case VariantType.Null:
            case VariantType.Void: return(null);

            case VariantType.Bool: return(stream.ReadByte() != 0);

            case VariantType.Int16: return(stream.ReadInt16());

            case VariantType.Uint16: return(stream.ReadUInt16());

            case VariantType.Int: return(stream.ReadInt32());

            case VariantType.Uint: return(stream.ReadUInt32());

            case VariantType.Int64: return(stream.ReadInt64());

            case VariantType.Uint64: return(stream.ReadUInt64());

            case VariantType.Float: return(stream.ReadSingle());

            case VariantType.Double: return(stream.ReadDouble());

            case VariantType.Pointer: return(new IntPtr((void *)stream.ReadUInt64()));

            case VariantType.String:
            {
                typeNameLength = stream.ReadInt32();
                var data = new char[typeNameLength];
                for (int i = 0; i < typeNameLength; i++)
                {
                    var c = stream.ReadUInt16();
                    data[i] = (char)(c ^ -14);
                }
                return(new string(data));
            }

            case VariantType.Object:
            {
                var id = stream.ReadGuid();
                return(FlaxEngine.Object.Find(ref id, type ?? typeof(FlaxEngine.Object)));
            }

            case VariantType.Asset:
            {
                var id = stream.ReadGuid();
                return(FlaxEngine.Object.Find(ref id, type ?? typeof(Asset)));
            }

            case VariantType.Blob: return(stream.ReadBytes(stream.ReadInt32()));

            case VariantType.Enum:
            {
                if (type == null)
                {
                    throw new Exception("Missing enum type of the Variant.");
                }
                return(Enum.ToObject(type, stream.ReadUInt64()));
            }

            case VariantType.Vector2: return(stream.ReadVector2());

            case VariantType.Vector3: return(stream.ReadVector3());

            case VariantType.Vector4: return(stream.ReadVector4());

            case VariantType.Int2: return(stream.ReadInt2());

            case VariantType.Int3: return(stream.ReadInt3());

            case VariantType.Int4: return(stream.ReadInt4());

            case VariantType.Color: return(stream.ReadColor());

            case VariantType.Guid: return(stream.ReadGuid());

            case VariantType.BoundingBox: return(stream.ReadBoundingBox());

            case VariantType.BoundingSphere: return(stream.ReadBoundingSphere());

            case VariantType.Quaternion: return(stream.ReadQuaternion());

            case VariantType.Transform: return(stream.ReadTransform());

            case VariantType.Rectangle: return(stream.ReadRectangle());

            case VariantType.Ray: return(stream.ReadRay());

            case VariantType.Matrix: return(stream.ReadMatrix());

            case VariantType.Array:
            {
                if (type == null)
                {
                    type = typeof(object[]);
                }
                else if (!type.IsArray)
                {
                    throw new Exception("Invalid arry type for the Variant array " + typeName);
                }
                var count  = stream.ReadInt32();
                var result = Array.CreateInstance(type.GetElementType(), count);
                for (int i = 0; i < count; i++)
                {
                    result.SetValue(stream.ReadVariant(), i);
                }
                return(result);
            }

            case VariantType.Dictionary:
            {
                var count  = stream.ReadInt32();
                var result = new Dictionary <object, object>();
                for (int i = 0; i < count; i++)
                {
                    result.Add(stream.ReadVariant(), stream.ReadVariant());
                }
                return(result);
            }

            case VariantType.Typename:
            {
                typeNameLength = stream.ReadInt32();
                var data = new byte[typeNameLength];
                for (int i = 0; i < typeNameLength; i++)
                {
                    var c = stream.ReadByte();
                    data[i] = (byte)(c ^ -14);
                }
                typeName = System.Text.Encoding.ASCII.GetString(data);
                return(TypeUtils.GetType(typeName));
            }

            case VariantType.ManagedObject:
            case VariantType.Structure:
            {
                if (type == null)
                {
                    throw new Exception("Missing type of the Variant typename " + typeName);
                }
                var format = stream.ReadByte();
                if (format == 0)
                {
                    // No Data
                }
                else if (format == 1)
                {
                    // Json
                    var json = stream.ReadStrAnsi(-71);
                    return(FlaxEngine.Json.JsonSerializer.Deserialize(json, type));
                }
                return(null);
            }

            default: throw new ArgumentOutOfRangeException($"Unknown Variant Type {variantType}." + (type != null ? $" Type: {type.FullName}" : string.Empty));
            }
        }
示例#23
0
        /// <summary>
        /// Updates the surface parameters group.
        /// </summary>
        private void UpdateSurfaceParametersGroup()
        {
            Profiler.BeginEvent("VisjectCM.UpdateSurfaceParametersGroup");

            // Remove the old one
            if (_surfaceParametersGroup != null)
            {
                _groups.Remove(_surfaceParametersGroup);
                _surfaceParametersGroup.Dispose();
                _surfaceParametersGroup = null;
            }

            // Check if surface has any parameters
            var parameters = _parametersGetter?.Invoke();
            int count      = parameters?.Count(x => x.IsPublic) ?? 0;

            if (count > 0)
            {
                // TODO: cache the allocated memory to reduce dynamic allocations
                if (_parameterSetNodeArchetype != null)
                {
                    count *= 2;
                }
                var archetypes     = new NodeArchetype[count];
                int archetypeIndex = 0;

                // ReSharper disable once PossibleNullReferenceException
                for (int i = 0; i < parameters.Count; i++)
                {
                    var param = parameters[i];
                    if (!param.IsPublic)
                    {
                        continue;
                    }

                    var node = (NodeArchetype)_parameterGetNodeArchetype.Clone();
                    node.Title                   = "Get " + param.Name;
                    node.DefaultValues[0]        = param.ID;
                    archetypes[archetypeIndex++] = node;

                    if (_parameterSetNodeArchetype != null)
                    {
                        node                         = (NodeArchetype)_parameterSetNodeArchetype.Clone();
                        node.Title                   = "Set " + param.Name;
                        node.DefaultValues[0]        = param.ID;
                        node.DefaultValues[1]        = TypeUtils.GetDefaultValue(param.Type);
                        archetypes[archetypeIndex++] = node;
                    }
                }

                var groupArchetype = new GroupArchetype
                {
                    GroupID    = 6,
                    Name       = "Surface Parameters",
                    Color      = new Color(52, 73, 94),
                    Archetypes = archetypes
                };

                var group = new VisjectCMGroup(this, groupArchetype)
                {
                    HeaderText = groupArchetype.Name
                };

                group.Close(false);
                archetypeIndex = 0;
                for (int i = 0; i < parameters.Count; i++)
                {
                    var param = parameters[i];
                    if (!param.IsPublic)
                    {
                        continue;
                    }

                    var item = new VisjectCMItem(group, groupArchetype, archetypes[archetypeIndex++])
                    {
                        Parent = group
                    };

                    if (_parameterSetNodeArchetype != null)
                    {
                        item = new VisjectCMItem(group, groupArchetype, archetypes[archetypeIndex++])
                        {
                            Parent = group
                        };
                    }
                }
                group.SortChildren();
                group.UnlockChildrenRecursive();
                group.Parent = _groupsPanel;
                _groups.Add(group);
                _surfaceParametersGroup = group;
            }

            Profiler.EndEvent();
        }
示例#24
0
        internal static VariantType ToVariantType(this Type type)
        {
            VariantType variantType;

            if (type == null)
            {
                variantType = VariantType.Null;
            }
            else if (type == typeof(void))
            {
                variantType = VariantType.Void;
            }
            else if (type == typeof(bool))
            {
                variantType = VariantType.Bool;
            }
            else if (type == typeof(short))
            {
                variantType = VariantType.Int16;
            }
            else if (type == typeof(ushort))
            {
                variantType = VariantType.Uint16;
            }
            else if (type == typeof(int))
            {
                variantType = VariantType.Int;
            }
            else if (type == typeof(uint))
            {
                variantType = VariantType.Uint;
            }
            else if (type == typeof(long))
            {
                variantType = VariantType.Int64;
            }
            else if (type == typeof(ulong))
            {
                variantType = VariantType.Uint64;
            }
            else if (type.IsEnum)
            {
                variantType = VariantType.Enum;
            }
            else if (type == typeof(float))
            {
                variantType = VariantType.Float;
            }
            else if (type == typeof(double))
            {
                variantType = VariantType.Double;
            }
            else if (type == typeof(IntPtr))
            {
                variantType = VariantType.Pointer;
            }
            else if (type == typeof(string))
            {
                variantType = VariantType.String;
            }
            else if (type == typeof(Type) || type == typeof(ScriptType))
            {
                variantType = VariantType.Typename;
            }
            else if (typeof(Asset).IsAssignableFrom(type))
            {
                variantType = VariantType.Asset;
            }
            else if (typeof(FlaxEngine.Object).IsAssignableFrom(type))
            {
                variantType = VariantType.Object;
            }
            else if (type == typeof(BoundingBox))
            {
                variantType = VariantType.BoundingBox;
            }
            else if (type == typeof(Transform))
            {
                variantType = VariantType.Transform;
            }
            else if (type == typeof(Ray))
            {
                variantType = VariantType.Ray;
            }
            else if (type == typeof(Matrix))
            {
                variantType = VariantType.Matrix;
            }
            else if (type == typeof(Vector2))
            {
                variantType = VariantType.Vector2;
            }
            else if (type == typeof(Vector3))
            {
                variantType = VariantType.Vector3;
            }
            else if (type == typeof(Vector4))
            {
                variantType = VariantType.Vector4;
            }
            else if (type == typeof(Int2))
            {
                variantType = VariantType.Int2;
            }
            else if (type == typeof(Int3))
            {
                variantType = VariantType.Int3;
            }
            else if (type == typeof(Int4))
            {
                variantType = VariantType.Int4;
            }
            else if (type == typeof(Color))
            {
                variantType = VariantType.Color;
            }
            else if (type == typeof(Guid))
            {
                variantType = VariantType.Guid;
            }
            else if (type == typeof(Quaternion))
            {
                variantType = VariantType.Quaternion;
            }
            else if (type == typeof(Rectangle))
            {
                variantType = VariantType.Rectangle;
            }
            else if (type == typeof(BoundingSphere))
            {
                variantType = VariantType.BoundingSphere;
            }
            else if (type.IsValueType)
            {
                variantType = VariantType.Structure;
            }
            else if (type == typeof(byte[]))
            {
                variantType = VariantType.Blob;
            }
            else if (type.IsArray)
            {
                variantType = VariantType.Array;
            }
            else if (type == typeof(Dictionary <object, object>))
            {
                variantType = VariantType.Dictionary;
            }
            else if (type.IsPointer || type.IsByRef)
            {
                // Find underlying type without `*` or `&`
                var typeName = type.FullName;
                type = TypeUtils.GetManagedType(typeName.Substring(0, typeName.Length - 1));
                return(ToVariantType(type));
            }
            else
            {
                variantType = VariantType.ManagedObject;
            }
            return(variantType);
        }
示例#25
0
 /// <summary>
 /// Gets the color for the connection.
 /// </summary>
 /// <param name="type">The connection type.</param>
 /// <param name="hint">The connection hint.</param>
 /// <param name="color">The color.</param>
 public void GetConnectionColor(ScriptType type, ConnectionsHint hint, out Color color)
 {
     if (type == ScriptType.Null)
     {
         color = Colors.Default;
     }
     else if (type.IsPointer || type.IsReference)
     {
         // Find underlying type without `*` or `&`
         var typeName = type.TypeName;
         type = TypeUtils.GetType(typeName.Substring(0, typeName.Length - 1));
         GetConnectionColor(type, hint, out color);
     }
     else if (type.IsArray)
     {
         GetConnectionColor(type.GetElementType(), hint, out color);
     }
     else if (type.Type == typeof(void))
     {
         color = Colors.Impulse;
     }
     else if (type.Type == typeof(bool))
     {
         color = Colors.Bool;
     }
     else if (type.Type == typeof(byte) || type.Type == typeof(sbyte) || type.Type == typeof(char) || type.Type == typeof(short) || type.Type == typeof(ushort) || type.Type == typeof(int) || type.Type == typeof(uint) || type.Type == typeof(long) || type.Type == typeof(ulong))
     {
         color = Colors.Integer;
     }
     else if (type.Type == typeof(float) || type.Type == typeof(double) || hint == ConnectionsHint.Scalar)
     {
         color = Colors.Float;
     }
     else if (type.Type == typeof(Vector2) || type.Type == typeof(Vector3) || type.Type == typeof(Vector4) || type.Type == typeof(Color))
     {
         color = Colors.Vector;
     }
     else if (type.Type == typeof(Float2) || type.Type == typeof(Float3) || type.Type == typeof(Float4))
     {
         color = Colors.Vector;
     }
     else if (type.Type == typeof(Double2) || type.Type == typeof(Double3) || type.Type == typeof(Double4))
     {
         color = Colors.Vector;
     }
     else if (type.Type == typeof(Int2) || type.Type == typeof(Int3) || type.Type == typeof(Int4))
     {
         color = Colors.Vector;
     }
     else if (type.Type == typeof(string))
     {
         color = Colors.String;
     }
     else if (type.Type == typeof(Quaternion))
     {
         color = Colors.Rotation;
     }
     else if (type.Type == typeof(Transform))
     {
         color = Colors.Transform;
     }
     else if (type.Type == typeof(BoundingBox) || type.Type == typeof(BoundingSphere) || type.Type == typeof(BoundingFrustum))
     {
         color = Colors.Bounds;
     }
     else if (type.IsEnum || hint == ConnectionsHint.Enum)
     {
         color = Colors.Enum;
     }
     else if (type.IsValueType)
     {
         color = Colors.Structures;
     }
     else if (ScriptType.FlaxObject.IsAssignableFrom(type) || type.IsInterface)
     {
         color = Colors.Object;
     }
     else if (hint == ConnectionsHint.Vector)
     {
         color = Colors.Vector;
     }
     else
     {
         color = Colors.Default;
     }
 }
示例#26
0
        protected override Expression VisitProjection(SqlProjectionExpression projectionExpression)
        {
            if (typeof(RelatedDataAccessObjects <>).IsAssignableFromIgnoreGenericParameters(projectionExpression.Type))
            {
                var elementType = projectionExpression.Type.GetGenericArguments()[0];
                var originalPlaceholderCount = 0;
                var currentPlaceholderCount  = originalPlaceholderCount;

                var replacedExpressions = new List <Expression>();
                projectionExpression = (SqlProjectionExpression)SqlOuterQueryReferencePlaceholderSubstitutor.Substitute(projectionExpression, ref currentPlaceholderCount, replacedExpressions);
                var values = replacedExpressions.Select(c => Expression.Convert(this.Visit(c), typeof(object))).ToList();
                var where = projectionExpression.Select.Where;

                var typeDescriptor = this.dataAccessModel.TypeDescriptorProvider.GetTypeDescriptor(elementType);
                var columns        = QueryBinder.GetColumnInfos(this.dataAccessModel.TypeDescriptorProvider, typeDescriptor.PersistedProperties);

                var columnExpression = (SqlColumnExpression)SqlExpressionFinder.FindFirst(where, c => c.NodeType == (ExpressionType)SqlExpressionType.Column);
                var match            = columns.Single(d => d.ColumnName == columnExpression.Name);

                var reference = Expression.Call(Expression.Constant(this.dataAccessModel), MethodInfoFastRef.DataAccessModelGetReferenceByValuesMethod.MakeGenericMethod(match.ForeignType.Type), Expression.NewArrayInit(typeof(object), values));
                var property  = typeDescriptor.GetRelationshipInfos().Single(c => c.ReferencingProperty == match.RootProperty).TargetProperty;

                return(Expression.Convert(Expression.Property(reference, property), this.dataAccessModel.GetConcreteTypeFromDefinitionType(property.PropertyType)));
            }
            else
            {
                var currentPlaceholderCount = 0;
                var replacedExpressions     = new List <Expression>();
                projectionExpression = (SqlProjectionExpression)SqlOuterQueryReferencePlaceholderSubstitutor.Substitute(projectionExpression, ref currentPlaceholderCount, replacedExpressions);

                var newColumnIndexes = projectionExpression.Select.Columns.Select((c, i) => new { c.Name, i }).ToDictionary(d => d.Name, d => d.i);

                var savedScope = this.scope;
                this.scope = new ProjectionBuilderScope(newColumnIndexes);
                var projectionProjector = Expression.Lambda(this.Visit(projectionExpression.Projector), this.objectProjector, this.dataReader, this.versionParameter, this.dynamicParameters, this.filterParameter);

                Expression rootKeys;

                if (this.scope.rootPrimaryKeys.Count > 0)
                {
                    rootKeys = Expression.Quote(Expression.Lambda <Func <IDataReader, object[]> >(Expression.NewArrayInit(typeof(object), this.scope.rootPrimaryKeys), this.dataReader));
                }
                else
                {
                    rootKeys = Expression.Constant(null, typeof(Expression <Func <IDataReader, object[]> >));
                }

                this.scope = savedScope;

                var values = replacedExpressions.Select(c => (Expression)Expression.Convert(this.Visit(c), typeof(object))).ToList();

                var method = TypeUtils.GetMethod <SqlQueryProvider>(c => c.BuildExecution(default(SqlProjectionExpression), default(LambdaExpression), default(object[]), default(Expression <Func <IDataReader, object[]> >)));

                MethodInfo evaluate;

                if (projectionExpression.Type.GetSequenceElementType() == null)
                {
                    evaluate = MethodInfoFastRef.ExecutionBuildResultEvaluateMethod.MakeGenericMethod(projectionExpression.Type);
                }
                else
                {
                    evaluate = MethodInfoFastRef.ExecutionBuildResultEvaluateMethod.MakeGenericMethod(typeof(IEnumerable <>).MakeGenericType(projectionExpression.Type.GetSequenceElementType()));
                }

                return(Expression.Call(Expression.Call(Expression.Property(this.objectProjector, "QueryProvider"), method, Expression.Constant(SqlAggregateProjectionNormalizer.Normalize(projectionExpression)), projectionProjector, Expression.NewArrayInit(typeof(object), values), rootKeys), evaluate));
            }
        }
示例#27
0
        private object CreateObject(ITypeSpec spec)
        {
            Type type = TypeUtils.GetType(spec.FullName);

            return(spec.IsViewModel || spec is IServiceSpec || spec.ContainsFacet <INotPersistedFacet>() ? CreateNotPersistedObject(type, spec is IServiceSpec) : objectPersistor.CreateObject(spec));
        }
示例#28
0
        /// <summary>
        /// Generates a syntax tree for the provided assemblies.
        /// </summary>
        /// <param name="targetAssembly">The assemblies used for accessibility checks, or <see langword="null"/> during runtime code generation.</param>
        /// <param name="assemblies">The assemblies to generate code for.</param>
        /// <returns>The generated syntax tree.</returns>
        private GeneratedSyntax GenerateCode(Assembly targetAssembly, List <Assembly> assemblies)
        {
            var features = new FeatureDescriptions();
            var members  = new List <MemberDeclarationSyntax>();

            // Expand the list of included assemblies and types.
            var knownAssemblies =
                new Dictionary <Assembly, KnownAssemblyAttribute>(
                    assemblies.ToDictionary(k => k, k => default(KnownAssemblyAttribute)));

            foreach (var attribute in assemblies.SelectMany(asm => asm.GetCustomAttributes <KnownAssemblyAttribute>()))
            {
                knownAssemblies[attribute.Assembly] = attribute;
            }

            if (logger.IsEnabled(LogLevel.Information))
            {
                logger.Info($"Generating code for assemblies: {string.Join(", ", knownAssemblies.Keys.Select(a => a.FullName))}");
            }

            // Get types from assemblies which reference Orleans and are not generated assemblies.
            var grainClasses    = new HashSet <Type>();
            var grainInterfaces = new HashSet <Type>();

            foreach (var pair in knownAssemblies)
            {
                var assembly = pair.Key;
                var treatTypesAsSerializable = pair.Value?.TreatTypesAsSerializable ?? false;
                foreach (var type in TypeUtils.GetDefinedTypes(assembly, this.logger))
                {
                    if (treatTypesAsSerializable || type.IsSerializable || TypeHasKnownBase(type))
                    {
                        string logContext = null;
                        if (logger.IsEnabled(LogLevel.Trace))
                        {
                            if (treatTypesAsSerializable)
                            {
                                logContext = $"known assembly {assembly.GetName().Name} where 'TreatTypesAsSerializable' = true";
                            }
                            else if (type.IsSerializable)
                            {
                                logContext = $"known assembly {assembly.GetName().Name} where type is [Serializable]";
                            }
                            else if (TypeHasKnownBase(type))
                            {
                                logContext = $"known assembly {assembly.GetName().Name} where type has known base type.";
                            }
                        }

                        serializableTypes.RecordType(type, targetAssembly, logContext);
                    }

                    // Include grain interfaces and classes.
                    var isGrainInterface = GrainInterfaceUtils.IsGrainInterface(type);
                    var isGrainClass     = TypeUtils.IsConcreteGrainClass(type);
                    if (isGrainInterface || isGrainClass)
                    {
                        // If code generation is being performed at runtime, the interface must be accessible to the generated code.
                        if (!TypeUtilities.IsAccessibleFromAssembly(type, targetAssembly))
                        {
                            if (this.logger.IsEnabled(LogLevel.Debug))
                            {
                                this.logger.Debug("Skipping inaccessible grain type, {0}", type.GetParseableName());
                            }

                            continue;
                        }

                        // Attempt to generate serializers for grain state classes, i.e, T in Grain<T>.
                        var baseType = type.BaseType;
                        if (baseType != null && baseType.IsConstructedGenericType)
                        {
                            foreach (var arg in baseType.GetGenericArguments())
                            {
                                string logContext = null;
                                if (logger.IsEnabled(LogLevel.Trace))
                                {
                                    logContext = "generic base type of " + type.GetLogFormat();
                                }
                                this.serializableTypes.RecordType(arg, targetAssembly, logContext);
                            }
                        }

                        // Skip classes generated by this generator.
                        if (IsOrleansGeneratedCode(type))
                        {
                            if (this.logger.IsEnabled(LogLevel.Debug))
                            {
                                this.logger.Debug("Skipping generated grain type, {0}", type.GetParseableName());
                            }

                            continue;
                        }

                        if (this.knownGrainTypes.Contains(type))
                        {
                            if (this.logger.IsEnabled(LogLevel.Debug))
                            {
                                this.logger.Debug("Skipping grain type {0} since it already has generated code.", type.GetParseableName());
                            }

                            continue;
                        }

                        if (isGrainClass)
                        {
                            if (this.logger.IsEnabled(LogLevel.Information))
                            {
                                this.logger.Info("Found grain implementation class: {0}", type.GetParseableName());
                            }

                            grainClasses.Add(type);
                        }

                        if (isGrainInterface)
                        {
                            if (this.logger.IsEnabled(LogLevel.Information))
                            {
                                this.logger.Info("Found grain interface: {0}", type.GetParseableName());
                            }

                            GrainInterfaceUtils.ValidateInterfaceRules(type);

                            grainInterfaces.Add(type);
                        }
                    }
                }
            }

            // Group the types by namespace and generate the required code in each namespace.
            foreach (var groupedGrainInterfaces in grainInterfaces.GroupBy(_ => CodeGeneratorCommon.GetGeneratedNamespace(_)))
            {
                var namespaceName    = groupedGrainInterfaces.Key;
                var namespaceMembers = new List <MemberDeclarationSyntax>();
                foreach (var grainInterface in groupedGrainInterfaces)
                {
                    var referenceTypeName = GrainReferenceGenerator.GetGeneratedClassName(grainInterface);
                    var invokerTypeName   = GrainMethodInvokerGenerator.GetGeneratedClassName(grainInterface);
                    namespaceMembers.Add(
                        GrainReferenceGenerator.GenerateClass(
                            grainInterface,
                            referenceTypeName,
                            encounteredType =>
                    {
                        string logContext = null;
                        if (logger.IsEnabled(LogLevel.Trace))
                        {
                            logContext = "used by grain type " + grainInterface.GetLogFormat();
                        }
                        this.serializableTypes.RecordType(encounteredType, targetAssembly, logContext);
                    }));
                    namespaceMembers.Add(GrainMethodInvokerGenerator.GenerateClass(grainInterface, invokerTypeName));
                    var genericTypeSuffix = GetGenericTypeSuffix(grainInterface.GetGenericArguments().Length);
                    features.GrainInterfaces.Add(
                        new GrainInterfaceDescription
                    {
                        Interface   = grainInterface.GetTypeSyntax(includeGenericParameters: false),
                        Reference   = SF.ParseTypeName(namespaceName + '.' + referenceTypeName + genericTypeSuffix),
                        Invoker     = SF.ParseTypeName(namespaceName + '.' + invokerTypeName + genericTypeSuffix),
                        InterfaceId = GrainInterfaceUtils.GetGrainInterfaceId(grainInterface)
                    });
                }

                members.Add(CreateNamespace(namespaceName, namespaceMembers));
            }

            foreach (var type in grainClasses)
            {
                features.GrainClasses.Add(
                    new GrainClassDescription
                {
                    ClassType = type.GetTypeSyntax(includeGenericParameters: false)
                });
            }

            // Generate serializers into their own namespace.
            var serializerNamespace = this.GenerateSerializers(targetAssembly, features);

            members.Add(serializerNamespace);

            // Add serialization metadata for the types which were encountered.
            this.AddSerializationTypes(features.Serializers, targetAssembly, knownAssemblies.Keys.ToList());

            foreach (var attribute in knownAssemblies.Keys.SelectMany(asm => asm.GetCustomAttributes <ConsiderForCodeGenerationAttribute>()))
            {
                this.serializableTypes.RecordType(attribute.Type, targetAssembly, "[ConsiderForCodeGeneration]");
                if (attribute.ThrowOnFailure && !this.serializableTypes.IsTypeRecorded(attribute.Type) && !this.serializableTypes.IsTypeIgnored(attribute.Type))
                {
                    throw new CodeGenerationException(
                              $"Found {attribute.GetType().Name} for type {attribute.Type.GetParseableName()}, but code" +
                              " could not be generated. Ensure that the type is accessible.");
                }
            }

            // Generate metadata directives for all of the relevant types.
            var(attributeDeclarations, memberDeclarations) = FeaturePopulatorGenerator.GenerateSyntax(targetAssembly, features);
            members.AddRange(memberDeclarations);

            var compilationUnit = SF.CompilationUnit().AddAttributeLists(attributeDeclarations.ToArray()).AddMembers(members.ToArray());

            return(new GeneratedSyntax
            {
                SourceAssemblies = knownAssemblies.Keys.ToList(),
                Syntax = compilationUnit
            });
        }
        protected IDbCommand BuildInsertCommandForDeflatedPredicated(TypeDescriptor typeDescriptor, DataAccessObject dataAccessObject, List <ObjectPropertyValue> updatedProperties)
        {
            var constantPlaceholdersCount = 0;
            var assignments = new List <Expression>();
            var success     = false;

            var requiresIdentityInsert = dataAccessObject.ToObjectInternal().HasAnyChangedPrimaryKeyServerSideProperties;

            var parameter1 = Expression.Parameter(typeDescriptor.Type);

            foreach (var updated in updatedProperties)
            {
                var placeholder = updated.Value as Expression ?? new SqlConstantPlaceholderExpression(constantPlaceholdersCount++, Expression.Constant(updated.Value, updated.PropertyType.CanBeNull() ? updated.PropertyType : updated.PropertyType.MakeNullable()));

                if (placeholder.Type != updated.PropertyType)
                {
                    placeholder = Expression.Convert(placeholder, updated.PropertyType);
                }

                var m = TypeUtils.GetMethod(() => default(DataAccessObject).SetColumnValue(default(string), default(int)))
                        .GetGenericMethodDefinition()
                        .MakeGenericMethod(typeDescriptor.Type, updated.PropertyType);

                assignments.Add(Expression.Call(null, m, parameter1, Expression.Constant(updated.PersistedName), placeholder));
            }

            var method = TypeUtils.GetMethod(() => default(IQueryable <DataAccessObject>).InsertHelper(default(Expression <Action <DataAccessObject> >), default(bool)))
                         .GetGenericMethodDefinition()
                         .MakeGenericMethod(typeDescriptor.Type);

            var source     = Expression.Constant(this.DataAccessModel.GetDataAccessObjects(typeDescriptor.Type));
            var selector   = Expression.Lambda(Expression.Block(assignments), parameter1);
            var expression = (Expression)Expression.Call(null, method, source, Expression.Quote(selector), Expression.Constant(requiresIdentityInsert));

            expression = SqlQueryProvider.Bind(this.DataAccessModel, this.sqlDataTypeProvider, expression);
            expression = SqlQueryProvider.Optimize(this.DataAccessModel, expression);
            var projectionExpression = expression as SqlProjectionExpression;

            expression = projectionExpression.Select.From;

            var result = this.SqlDatabaseContext.SqlQueryFormatterManager.Format(expression);

            IDbCommand command = null;

            try
            {
                command             = this.CreateCommand();
                command.CommandText = result.CommandText;

                var cachedValue = new SqlCachedUpdateInsertFormatValue {
                    formatResult = result
                };

                this.FillParameters(command, cachedValue, null, null);

                success = true;

                return(command);
            }
            finally
            {
                if (!success)
                {
                    command?.Dispose();
                }
            }
        }
示例#30
0
        /// <code>
        /// stloc s(value)
        /// stloc l(ldloc s)
        /// stobj(..., ldloc s)
        ///   where ... is pure and does not use s or l,
        ///   and where neither the 'stloc s' nor the 'stobj' truncates
        /// -->
        /// stloc l(stobj (..., value))
        /// </code>
        /// e.g. used for inline assignment to instance field
        ///
        /// -or-
        ///
        /// <code>
        /// stloc s(value)
        /// stobj (..., ldloc s)
        ///   where ... is pure and does not use s, and where the 'stobj' does not truncate
        /// -->
        /// stloc s(stobj (..., value))
        /// </code>
        /// e.g. used for inline assignment to static field
        ///
        /// -or-
        ///
        /// <code>
        /// stloc s(value)
        /// call set_Property(..., ldloc s)
        ///   where the '...' arguments are pure and not using 's'
        /// -->
        /// stloc s(Block InlineAssign { call set_Property(..., stloc i(value)); final: ldloc i })
        ///   new temporary 'i' has type of the property; transform only valid if 'stloc i' doesn't truncate
        /// </code>
        bool TransformInlineAssignmentStObjOrCall(Block block, int pos)
        {
            var inst = block.Instructions[pos] as StLoc;

            // in some cases it can be a compiler-generated local
            if (inst == null || (inst.Variable.Kind != VariableKind.StackSlot && inst.Variable.Kind != VariableKind.Local))
            {
                return(false);
            }
            if (IsImplicitTruncation(inst.Value, inst.Variable.Type, context.TypeSystem))
            {
                // 'stloc s' is implicitly truncating the value
                return(false);
            }
            ILVariable local;
            int        nextPos;

            if (block.Instructions[pos + 1] is StLoc localStore)               // with extra local
            {
                if (localStore.Variable.Kind != VariableKind.Local || !localStore.Value.MatchLdLoc(inst.Variable))
                {
                    return(false);
                }
                // if we're using an extra local, we'll delete "s", so check that that doesn't have any additional uses
                if (!(inst.Variable.IsSingleDefinition && inst.Variable.LoadCount == 2))
                {
                    return(false);
                }
                local   = localStore.Variable;
                nextPos = pos + 2;
            }
            else
            {
                local      = inst.Variable;
                localStore = null;
                nextPos    = pos + 1;
            }
            if (block.Instructions[nextPos] is StObj stobj)
            {
                if (!stobj.Value.MatchLdLoc(inst.Variable))
                {
                    return(false);
                }
                if (!SemanticHelper.IsPure(stobj.Target.Flags) || inst.Variable.IsUsedWithin(stobj.Target))
                {
                    return(false);
                }
                var   pointerType = stobj.Target.InferType(context.TypeSystem);
                IType newType     = stobj.Type;
                if (TypeUtils.IsCompatiblePointerTypeForMemoryAccess(pointerType, stobj.Type))
                {
                    if (pointerType is ByReferenceType byref)
                    {
                        newType = byref.ElementType;
                    }
                    else if (pointerType is PointerType pointer)
                    {
                        newType = pointer.ElementType;
                    }
                }
                if (IsImplicitTruncation(inst.Value, newType, context.TypeSystem))
                {
                    // 'stobj' is implicitly truncating the value
                    return(false);
                }
                context.Step("Inline assignment stobj", stobj);
                stobj.Type = newType;
                block.Instructions.Remove(localStore);
                block.Instructions.Remove(stobj);
                stobj.Value = inst.Value;
                inst.ReplaceWith(new StLoc(local, stobj));
                // note: our caller will trigger a re-run, which will call HandleStObjCompoundAssign if applicable
                return(true);
            }
            else if (block.Instructions[nextPos] is CallInstruction call)
            {
                // call must be a setter call:
                if (!(call.OpCode == OpCode.Call || call.OpCode == OpCode.CallVirt))
                {
                    return(false);
                }
                if (call.ResultType != StackType.Void || call.Arguments.Count == 0)
                {
                    return(false);
                }
                if (!call.Method.Equals((call.Method.AccessorOwner as IProperty)?.Setter))
                {
                    return(false);
                }
                if (!call.Arguments.Last().MatchLdLoc(inst.Variable))
                {
                    return(false);
                }
                foreach (var arg in call.Arguments.SkipLast(1))
                {
                    if (!SemanticHelper.IsPure(arg.Flags) || inst.Variable.IsUsedWithin(arg))
                    {
                        return(false);
                    }
                }
                if (IsImplicitTruncation(inst.Value, call.Method.Parameters.Last().Type, context.TypeSystem))
                {
                    // setter call is implicitly truncating the value
                    return(false);
                }
                // stloc s(Block InlineAssign { call set_Property(..., stloc i(value)); final: ldloc i })
                context.Step("Inline assignment call", call);
                block.Instructions.Remove(localStore);
                block.Instructions.Remove(call);
                var newVar = context.Function.RegisterVariable(VariableKind.StackSlot, call.Method.Parameters.Last().Type);
                call.Arguments[call.Arguments.Count - 1] = new StLoc(newVar, inst.Value);
                var inlineBlock = new Block(BlockKind.CallInlineAssign)
                {
                    Instructions     = { call },
                    FinalInstruction = new LdLoc(newVar)
                };
                inst.ReplaceWith(new StLoc(local, inlineBlock));
                // because the ExpressionTransforms don't look into inline blocks, manually trigger HandleCallCompoundAssign
                if (HandleCompoundAssign(call, context))
                {
                    // if we did construct a compound assignment, it should have made our inline block redundant:
                    if (inlineBlock.Instructions.Single().MatchStLoc(newVar, out var compoundAssign))
                    {
                        Debug.Assert(newVar.IsSingleDefinition && newVar.LoadCount == 1);
                        inlineBlock.ReplaceWith(compoundAssign);
                    }
                }
                return(true);
            }
            else
            {
                return(false);
            }
        }