public NetworkCompatibility(
     CompatibilityLevel compatibility    = CompatibilityLevel.EveryoneMustHaveMod,
     VersionStrictness versionStrictness = VersionStrictness.EveryoneNeedSameModVersion)
 {
     CompatibilityLevel = compatibility;
     VersionStrictness  = versionStrictness;
 }
 /// <summary>
 /// Gets the hash code
 /// </summary>
 /// <returns>Hash code</returns>
 public override int GetHashCode()
 {
     unchecked // Overflow is fine, just wrap
     {
         var hashCode = 41;
         // Suitable nullity checks etc, of course :)
         if (Name != null)
         {
             hashCode = hashCode * 59 + Name.GetHashCode();
         }
         if (IsCompatible != null)
         {
             hashCode = hashCode * 59 + IsCompatible.GetHashCode();
         }
         if (CompatibilityLevel != null)
         {
             hashCode = hashCode * 59 + CompatibilityLevel.GetHashCode();
         }
         if (Confidence != null)
         {
             hashCode = hashCode * 59 + Confidence.GetHashCode();
         }
         if (ConfidenceDescription != null)
         {
             hashCode = hashCode * 59 + ConfidenceDescription.GetHashCode();
         }
         return(hashCode);
     }
 }
Exemple #3
0
        public int OnAfterOpenProject(IVsHierarchy pHierarchy, int fAdded)
        {
            // Only check this project if the solution is opened and we haven't already warned at the maximum level. Note that fAdded
            // is true for both add and a reload of an unloaded project
            if (SolutionOpen && fAdded == 1 && CompatibilityLevelWarnedForCurrentSolution != CompatibilityLevel.NotSupported)
            {
                UnconfiguredProject? project = pHierarchy.AsUnconfiguredProject();
                if (project != null)
                {
                    _threadHandling.Value.RunAndForget(async () =>
                    {
                        // Run on the background
                        await TaskScheduler.Default;

                        VersionCompatibilityData compatData = GetVersionCompatibilityData();

                        // We need to check if this project has been newly created. Our projects will implement IProjectCreationState -we can 
                        // skip any that don't
                        if (IsNewlyCreated(project))
                        {
                            bool isPreviewSDKInUse = await IsPreviewSDKInUseAsync();
                            CompatibilityLevel compatLevel = await GetProjectCompatibilityAsync(project, compatData, isPreviewSDKInUse);
                            if (compatLevel != CompatibilityLevel.Recommended)
                            {
                                await WarnUserOfIncompatibleProjectAsync(compatLevel, compatData, isPreviewSDKInUse);
                            }
                        }
                    }, unconfiguredProject: null);
                }
            }

            return HResult.OK;
        }
Exemple #4
0
        public int OnAfterOpenProject(IVsHierarchy pHierarchy, int fAdded)
        {
            // Only check this project if the solution is opened and we haven't already warned at the maximum level. Note that fAdded
            // is true for both add and a reload of an unloaded project
            if (_solutionOpened && fAdded == 1 && _compatibilityLevelWarnedForThisSolution != CompatibilityLevel.NotSupported)
            {
                UnconfiguredProject project = pHierarchy.AsUnconfiguredProject();
                if (project != null)
                {
                    _threadHandling.Value.JoinableTaskFactory.RunAsync(async() =>
                    {
                        // Run on the background
                        await TaskScheduler.Default;

                        VersionCompatibilityData compatData = GetVersionCmpatibilityData();

                        // We need to check if this project has been newly created. Our projects will implement IProjectCreationState -we can
                        // skip any that don't
                        IProjectCreationState projectCreationState = project.Services.ExportProvider.GetExportedValueOrDefault <IProjectCreationState>();
                        if (projectCreationState != null && !projectCreationState.WasNewlyCreated)
                        {
                            CompatibilityLevel compatLevel = await GetProjectCompatibilityAsync(project, compatData).ConfigureAwait(false);
                            if (compatLevel != CompatibilityLevel.Recommended)
                            {
                                await WarnUserOfIncompatibleProjectAsync(compatLevel, compatData).ConfigureAwait(false);
                            }
                        }
                    });
                }
            }

            return(VSConstants.S_OK);
        }
Exemple #5
0
        private async Task CheckCompatibilityAsync()
        {
            // Run on the background
            await TaskScheduler.Default;

            VersionCompatibilityData compatDataToUse = GetVersionCompatibilityData();
            CompatibilityLevel finalCompatLevel = CompatibilityLevel.Recommended;
            IProjectService projectService = _projectServiceAccessor.Value.GetProjectService();
            IEnumerable<UnconfiguredProject> projects = projectService.LoadedUnconfiguredProjects;
            bool isPreviewSDKInUse = await IsPreviewSDKInUseAsync();
            foreach (UnconfiguredProject project in projects)
            {
                // Track the most severe compatibility level
                CompatibilityLevel compatLevel = await GetProjectCompatibilityAsync(project, compatDataToUse, isPreviewSDKInUse);
                if (compatLevel != CompatibilityLevel.Recommended && compatLevel > finalCompatLevel)
                {
                    finalCompatLevel = compatLevel;
                }
            }

            if (finalCompatLevel != CompatibilityLevel.Recommended)
            {

                // Warn the user.
                await WarnUserOfIncompatibleProjectAsync(finalCompatLevel, compatDataToUse, isPreviewSDKInUse);
            }

            // Used so we know when to process newly added projects
            SolutionOpen = true;
        }
Exemple #6
0
 public int OnAfterCloseSolution(object pUnkReserved)
 {
     // Clear state flags
     _compatibilityLevelWarnedForThisSolution = CompatibilityLevel.Recommended;
     _solutionOpened = false;
     return(VSConstants.S_OK);
 }
Exemple #7
0
        /// <summary>
        /// Fired when the solution load process is fully complete, including all background loading
        /// of projects. This event always fires after the initial opening of a solution
        /// </summary>
        public int OnAfterBackgroundSolutionLoadComplete()
        {
            // Schedule this to run on idle
            _threadHandling.Value.JoinableTaskFactory.RunAsync(async() =>
            {
                // Run on the background
                await TaskScheduler.Default;

                VersionCompatibilityData compatDataToUse = GetVersionCmpatibilityData();

                CompatibilityLevel finalCompatLevel        = CompatibilityLevel.Recommended;
                IProjectService projectService             = _projectServiceAccessor.Value.GetProjectService();
                IEnumerable <UnconfiguredProject> projects = projectService.LoadedUnconfiguredProjects;
                foreach (UnconfiguredProject project in projects)
                {
                    // Track the most severe compatibility level
                    CompatibilityLevel compatLevel = await GetProjectCompatibilityAsync(project, compatDataToUse).ConfigureAwait(false);
                    if (compatLevel != CompatibilityLevel.Recommended && compatLevel > finalCompatLevel)
                    {
                        finalCompatLevel = compatLevel;
                    }
                }

                if (finalCompatLevel != CompatibilityLevel.Recommended)
                {
                    // Warn the user.
                    await WarnUserOfIncompatibleProjectAsync(finalCompatLevel, compatDataToUse).ConfigureAwait(false);
                }

                // Used so we know when to process newly added projects
                _solutionOpened = true;
            });

            return(VSConstants.S_OK);
        }
Exemple #8
0
 public DataCompatibilityRangeTheoryTestCase(
     CompatibilityLevel compatibilityLevel,
     IMessageSink diagnosticMessageSink,
     TestMethodDisplay defaultMethodDisplay,
     ITestMethod testMethod)
     : base(diagnosticMessageSink, defaultMethodDisplay, testMethod, new object[] { compatibilityLevel })
 {
 }
 public static DecimalSerializer Create(CompatibilityLevel compatibilityLevel)
 {
     if (compatibilityLevel < CompatibilityLevel.Level300)
     {
         return(s_BclDecimal ??= new DecimalSerializer(Variant.BclDecimal));
     }
     return(s_String ??= new DecimalSerializer(Variant.String));
 }
Exemple #10
0
 internal FieldChange(ChangeType changeType, ChangeCategory category, CompatibilityLevel compatibility, FieldDefinition field)
     : base(changeType, category, compatibility)
 {
     if (field == null)
     {
         throw new ArgumentNullException("field");
     }
     _field = field;
 }
 internal MethodChange(ChangeType changeType, ChangeCategory category, CompatibilityLevel compatibility, MethodDefinition method)
     : base(changeType, category, compatibility)
 {
     if (method == null)
     {
         throw new ArgumentNullException("method");
     }
     _method = method;
 }
        static DataCompatibilityRangeFactAttribute()
        {
            var compatibilityLevels = Enum.GetValues(typeof(CompatibilityLevel))
                                      .Cast <CompatibilityLevel>()
                                      .ToArray();

            PossibleMinLevel          = compatibilityLevels.Min();
            PossibleMaxExcludingLevel = compatibilityLevels.Max() + 1;
        }
Exemple #13
0
 internal TypeChange(ChangeType changeType, ChangeCategory category, CompatibilityLevel compatibility, TypeDefinition type)
     : base(changeType, category, compatibility)
 {
     if (type == null)
     {
         throw new ArgumentNullException("type");
     }
     _type = type;
 }
 internal static GuidSerializer Create(CompatibilityLevel compatibilityLevel, DataFormat dataFormat)
 {
     if (compatibilityLevel < CompatibilityLevel.Level300)
     {
         return(s_Legacy ??= new GuidSerializer(Variant.BclGuid));
     }
     if (dataFormat == DataFormat.FixedSize)
     {
         return(s_Bytes ??= new GuidSerializer(Variant.GuidBytes));
     }
     return(s_String ??= new GuidSerializer(Variant.GuidString));
 }
Exemple #15
0
        private async Task WarnUserOfIncompatibleProjectAsync(CompatibilityLevel compatLevel, VersionCompatibilityData compatData)
        {
            // Warn the user.
            await _threadHandling.Value.SwitchToUIThread();

            // Check if already warned - this could happen in the off chance two projects are added very quickly since the detection work is
            // scheduled on idle.
            if (_compatibilityLevelWarnedForThisSolution < compatLevel)
            {
                // Only want to warn once per solution
                _compatibilityLevelWarnedForThisSolution = compatLevel;

                IVsUIShell uiShell = await _vsUIShellService.GetValueAsync();

                uiShell.GetAppName(out string caption);

                if (compatLevel == CompatibilityLevel.Supported)
                {
                    // Get current dontShowAgain value
                    ISettingsManager settingsManager = await _settingsManagerService.GetValueAsync();

                    bool suppressPrompt = false;
                    if (settingsManager != null)
                    {
                        suppressPrompt = settingsManager.GetValueOrDefault(SuppressDotNewCoreWarningKey, defaultValue: false);
                    }

                    if (!suppressPrompt)
                    {
                        string msg = string.Format(compatData.OpenSupportedMessage, compatData.SupportedVersion.Major, compatData.SupportedVersion.Minor);
                        suppressPrompt = _dialogServices.Value.DontShowAgainMessageBox(caption, msg, VSResources.DontShowAgain, false, VSResources.LearnMore, SupportedLearnMoreFwlink);
                        if (suppressPrompt && settingsManager != null)
                        {
                            await settingsManager.SetValueAsync(SuppressDotNewCoreWarningKey, suppressPrompt, isMachineLocal : true);
                        }
                    }
                }
                else
                {
                    string msg;
                    if (compatData.UnsupportedVersion != null)
                    {
                        msg = string.Format(compatData.OpenUnsupportedMessage, compatData.UnsupportedVersion.Major, compatData.UnsupportedVersion.Minor);
                    }
                    else
                    {
                        msg = string.Format(compatData.OpenUnsupportedMessage, compatData.SupportedVersion.Major, compatData.SupportedVersion.Minor);
                    }

                    _dialogServices.Value.DontShowAgainMessageBox(caption, msg, null, false, VSResources.LearnMore, UnsupportedLearnMoreFwlink);
                }
            }
        }
Exemple #16
0
 private static void TryGetNetworkCompatibilityArguments(IList <CustomAttributeArgument> attributeArguments,
                                                         out CompatibilityLevel compatibilityLevel, out VersionStrictness versionStrictness)
 {
     if (attributeArguments[0].Value is int && attributeArguments[1].Value is int)
     {
         compatibilityLevel = (CompatibilityLevel)attributeArguments[0].Value;
         versionStrictness  = (VersionStrictness)attributeArguments[1].Value;
     }
     else
     {
         compatibilityLevel = CompatibilityLevel.EveryoneMustHaveMod;
         versionStrictness  = VersionStrictness.EveryoneNeedSameModVersion;
     }
 }
Exemple #17
0
        public static CompatibilityObject Create(CompatibilityLevel level)
        {
            if (level == Messages.CompatibilityLevel.NotSet)
            {
                return(new CompatibilityObject
                {
                    Compatibility = null
                });
            }

            return(new CompatibilityObject
            {
                Compatibility = Enum.GetName(typeof(CompatibilityLevel), level).ToUpperInvariant()
            });
        }
Exemple #18
0
        /// <summary>
        /// Returns true if BrandedFoodObjectDietFlags instances are equal
        /// </summary>
        /// <param name="other">Instance of BrandedFoodObjectDietFlags to be compared</param>
        /// <returns>Boolean</returns>
        public bool Equals(BrandedFoodObjectDietFlags other)
        {
            if (ReferenceEquals(null, other))
            {
                return(false);
            }
            if (ReferenceEquals(this, other))
            {
                return(true);
            }

            return
                ((
                     Ingredient == other.Ingredient ||
                     Ingredient != null &&
                     Ingredient.Equals(other.Ingredient)
                     ) &&
                 (
                     IngredientDescription == other.IngredientDescription ||
                     IngredientDescription != null &&
                     IngredientDescription.Equals(other.IngredientDescription)
                 ) &&
                 (
                     DietLabel == other.DietLabel ||
                     DietLabel != null &&
                     DietLabel.Equals(other.DietLabel)
                 ) &&
                 (
                     IsCompatible == other.IsCompatible ||
                     IsCompatible != null &&
                     IsCompatible.Equals(other.IsCompatible)
                 ) &&
                 (
                     CompatibilityLevel == other.CompatibilityLevel ||
                     CompatibilityLevel != null &&
                     CompatibilityLevel.Equals(other.CompatibilityLevel)
                 ) &&
                 (
                     CompatibilityDescription == other.CompatibilityDescription ||
                     CompatibilityDescription != null &&
                     CompatibilityDescription.Equals(other.CompatibilityDescription)
                 ) &&
                 (
                     IsAllergen == other.IsAllergen ||
                     IsAllergen != null &&
                     IsAllergen.Equals(other.IsAllergen)
                 ));
        }
 static bool IsValidKey(Type type, CompatibilityLevel compatibilityLevel, DataFormat dataFormat)
 {
     if (type == null)
     {
         return(false);
     }
     if (type.IsEnum)
     {
         return(true);
     }
     if (type == typeof(string))
     {
         return(true);
     }
     if (!type.IsValueType)
     {
         return(false);
     }
     if (Nullable.GetUnderlyingType(type) != null)
     {
         return(false);
     }
     switch (Type.GetTypeCode(type))
     {
     case TypeCode.SByte:
     case TypeCode.Int16:
     case TypeCode.Int32:
     case TypeCode.Int64:
     case TypeCode.Byte:
     case TypeCode.UInt16:
     case TypeCode.UInt32:
     case TypeCode.UInt64:
         return(true);
     }
     if (compatibilityLevel >= CompatibilityLevel.Level300)
     {   // we'll allow guids as strings as keys
         if (type == typeof(Guid) && dataFormat != DataFormat.FixedSize)
         {
             return(true);
         }
     }
     return(false);
 }
        /// <summary>
        /// Returns true if BrandedFoodObjectDietLabelsGlutenFree instances are equal
        /// </summary>
        /// <param name="other">Instance of BrandedFoodObjectDietLabelsGlutenFree to be compared</param>
        /// <returns>Boolean</returns>
        public bool Equals(BrandedFoodObjectDietLabelsGlutenFree other)
        {
            if (ReferenceEquals(null, other))
            {
                return(false);
            }
            if (ReferenceEquals(this, other))
            {
                return(true);
            }

            return
                ((
                     Name == other.Name ||
                     Name != null &&
                     Name.Equals(other.Name)
                     ) &&
                 (
                     IsCompatible == other.IsCompatible ||
                     IsCompatible != null &&
                     IsCompatible.Equals(other.IsCompatible)
                 ) &&
                 (
                     CompatibilityLevel == other.CompatibilityLevel ||
                     CompatibilityLevel != null &&
                     CompatibilityLevel.Equals(other.CompatibilityLevel)
                 ) &&
                 (
                     Confidence == other.Confidence ||
                     Confidence != null &&
                     Confidence.Equals(other.Confidence)
                 ) &&
                 (
                     ConfidenceDescription == other.ConfidenceDescription ||
                     ConfidenceDescription != null &&
                     ConfidenceDescription.Equals(other.ConfidenceDescription)
                 ));
        }
        internal bool IsValidProtobufMap(RuntimeTypeModel model, CompatibilityLevel compatibilityLevel, DataFormat dataFormat)
        {
            if (!IsMap)
            {
                return(false);
            }
            ResolveMapTypes(out var key, out var value);

            // the key must an any integral or string type (not floating point or bytes)
            if (!IsValidKey(key, compatibilityLevel, dataFormat))
            {
                return(false);
            }

            // the value cannot be repeated (neither can key, but we ruled that out above)
            var repeated = model == null?RepeatedSerializers.TryGetRepeatedProvider(value) : model.TryGetRepeatedProvider(value);

            if (repeated != null)
            {
                return(false);
            }

            return(true);
Exemple #22
0
 /// <summary>
 /// Gets the hash code
 /// </summary>
 /// <returns>Hash code</returns>
 public override int GetHashCode()
 {
     unchecked // Overflow is fine, just wrap
     {
         var hashCode = 41;
         // Suitable nullity checks etc, of course :)
         if (Ingredient != null)
         {
             hashCode = hashCode * 59 + Ingredient.GetHashCode();
         }
         if (IngredientDescription != null)
         {
             hashCode = hashCode * 59 + IngredientDescription.GetHashCode();
         }
         if (DietLabel != null)
         {
             hashCode = hashCode * 59 + DietLabel.GetHashCode();
         }
         if (IsCompatible != null)
         {
             hashCode = hashCode * 59 + IsCompatible.GetHashCode();
         }
         if (CompatibilityLevel != null)
         {
             hashCode = hashCode * 59 + CompatibilityLevel.GetHashCode();
         }
         if (CompatibilityDescription != null)
         {
             hashCode = hashCode * 59 + CompatibilityDescription.GetHashCode();
         }
         if (IsAllergen != null)
         {
             hashCode = hashCode * 59 + IsAllergen.GetHashCode();
         }
         return(hashCode);
     }
 }
Exemple #23
0
        private void OnDialogLoad(object sender, EventArgs eventArgs)
        {
            CompatibilityLevel compatibilityLevel = m_compatibilityReport.CompatibilityLevel;

            m_overallCompatibilityValue.Text = compatibilityLevel.ToString();

            foreach (CompatibilityNote compatibilityNote in m_compatibilityReport.CompatibilityNotes)
            {
                Image image = null;
                switch (compatibilityNote.CompatibilityLevel)
                {
                case CompatibilityLevel.Full: image = Properties.Resources.MapCompatibilityFull; break;

                case CompatibilityLevel.Partial: image = Properties.Resources.MapCompatibilityPartial; break;

                case CompatibilityLevel.None: image = Properties.Resources.MapCompatibilityNone; break;
                }
                m_notesDataGridView.Rows.Add(
                    new object[] { image, compatibilityNote.CompatibilityLevel, compatibilityNote.Remarks });
            }
            m_notesDataGridView.ClearSelection();

            m_okButton.Enabled = compatibilityLevel != CompatibilityLevel.None;
        }
Exemple #24
0
        /// <summary>
        /// Gets the SqlServerVersion for the specified CompatibilityLevel.
        /// </summary>
        public static SqlServerVersion GetSqlServerVersion(CompatibilityLevel compatibilityLevel)
        {
            switch (compatibilityLevel)
            {
            case CompatibilityLevel.Version100:
                return(SqlServerVersion.Version100);

            // If the compatibility level is 90 (2005) then we target version 90
            case CompatibilityLevel.Version90:
                return(SqlServerVersion.Version90);

            // If the compatibility level is 80 (2000) then we target version 80
            // If the compatibility level is 80 (2000) or less then we target version 80.
            case CompatibilityLevel.Version80:
            case CompatibilityLevel.Version70:
            case CompatibilityLevel.Version65:
            case CompatibilityLevel.Version60:
                return(SqlServerVersion.Version80);

            // Default target version 110 (2012)
            default:
                return(SqlServerVersion.Version110);
            }
        }
Exemple #25
0
 internal TypeChange(ChangeType changeType, ChangeCategory category, CompatibilityLevel compatibility, TypeDefinition type)
     : base(changeType, category, compatibility)
 {
     if (type == null) throw new ArgumentNullException("type");
     _type = type;
 }
Exemple #26
0
 /// <summary>
 /// Constructs a compatiblity note with the given level and
 /// remarks
 /// </summary>
 /// <param name="compatibilityLevel">Level of compatiblity</param>
 /// <param name="remarks">Any applicable remarks</param>
 public CompatibilityNote(
     CompatibilityLevel compatibilityLevel, string remarks)
 {
     m_compatibilityLevel = compatibilityLevel;
     m_remarks = remarks;
 }
 internal MethodChangedChange(ChangeCategory category, CompatibilityLevel compatibility, MethodDefinition method, IEnumerable<MethodDefinition> overloads)
     : base(ChangeType.MethodChanged, category, compatibility, method)
 {
     _overloads = overloads;
 }
Exemple #28
0
 // note: in IsKnownType and CanSerialize we want to avoid asking for the serializer from
 // the model unless we actually need it, as that can cause re-entrancy loops
 protected override bool IsKnownType(TypeModel model, CompatibilityLevel ambient) => model != null && model.IsKnownType <T>(ambient);
Exemple #29
0
        public async Task <CompatibilityLevel> PutSubjectConfig(string subject, CompatibilityLevel level)
        {
            var compatibilityObject = await RunRequest <CompatibilityObject, CompatibilityObject>($"/config/{subject}", HttpMethod.Put, CompatibilityObject.Create(level));

            return(ParseCompatibilityEnum(compatibilityObject));
        }
Exemple #30
0
 /// <summary>
 ///     Network Compatibility Attribute
 /// </summary>
 /// <param name="enforceMod"></param>
 /// <param name="enforceVersion"></param>
 public NetworkCompatibilityAttribute(CompatibilityLevel enforceMod, VersionStrictness enforceVersion)
 {
     EnforceModOnClients = enforceMod;
     EnforceSameVersion  = enforceVersion;
 }
Exemple #31
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ChangeType"/> class using the specified
 /// change <paramref name="category"/> and <paramref name="compatibility"/> level.
 /// </summary>
 /// <param name="changeType">
 /// The <see cref="ChangeType"/> indicating the type of the change.
 /// </param>
 /// <param name="category">
 /// The <see cref="ChangeCategory"/> indicating whether or not this is a breaking change.
 /// </param>
 /// <param name="compatibility">
 /// The <see cref="CompatibilityLevel"/> indicating whether this change breaks binary or 
 /// source compatibility.
 /// </param>
 protected Change(ChangeType changeType, ChangeCategory category, CompatibilityLevel compatibility)
 {
     ChangeType = changeType;
     Category = category;
     Compatibility = compatibility;
 }
 internal FieldChange(ChangeType changeType, ChangeCategory category, CompatibilityLevel compatibility, FieldDefinition field)
     : base(changeType, category, compatibility)
 {
     if (field == null) throw new ArgumentNullException("field");
     _field = field;
 }
Exemple #33
0
 internal static bool IsKnownType(Type type, TypeModel model, CompatibilityLevel ambient)
 => Get(type).IsKnownType(model, ambient);
 internal MethodChange(ChangeType changeType, ChangeCategory category, CompatibilityLevel compatibility, MethodDefinition method)
     : base(changeType, category, compatibility)
 {
     if (method == null) throw new ArgumentNullException("method");
     _method = method;
 }
Exemple #35
0
 /// <summary>
 /// Constructs a compatiblity note with the given level and
 /// remarks
 /// </summary>
 /// <param name="compatibilityLevel">Level of compatiblity</param>
 /// <param name="remarks">Any applicable remarks</param>
 public CompatibilityNote(
     CompatibilityLevel compatibilityLevel, string remarks)
 {
     m_compatibilityLevel = compatibilityLevel;
     m_remarks            = remarks;
 }
Exemple #36
0
        public TupleSerializer(RuntimeTypeModel model, ConstructorInfo ctor, MemberInfo[] members, SerializerFeatures features, CompatibilityLevel compatibilityLevel)
        {
            this.ctor    = ctor ?? throw new ArgumentNullException(nameof(ctor));
            this.members = members ?? throw new ArgumentNullException(nameof(members));
            this.tails   = new IRuntimeProtoSerializerNode[members.Length];

            Features = features;
            ParameterInfo[] parameters = ctor.GetParameters();
            for (int i = 0; i < members.Length; i++)
            {
                Type finalType = parameters[i].ParameterType;

                var  repeated = model.TryGetRepeatedProvider(finalType);
                Type tmp      = repeated?.ItemType ?? finalType;

                bool asReference = false;
                int  typeIndex   = model.FindOrAddAuto(tmp, false, true, false, compatibilityLevel);
                if (typeIndex >= 0)
                {
                    asReference = model[tmp].AsReferenceDefault;
                }
                IRuntimeProtoSerializerNode tail = ValueMember.TryGetCoreSerializer(model, DataFormat.Default, compatibilityLevel, tmp, out WireType wireType, asReference, false, false, true), serializer;
                if (tail == null)
                {
                    throw new InvalidOperationException("No serializer defined for type: " + tmp.FullName);
                }

                if (repeated == null)
                {
                    serializer = new TagDecorator(i + 1, wireType, false, tail);
                }
                else if (repeated.IsMap)
                {
                    serializer = ValueMember.CreateMap(repeated, model, DataFormat.Default, compatibilityLevel, DataFormat.Default, DataFormat.Default, asReference, false, true, false, i + 1);
                }
                else
                {
                    SerializerFeatures listFeatures = wireType.AsFeatures() | SerializerFeatures.OptionPackedDisabled;
                    serializer = RepeatedDecorator.Create(repeated, i + 1, listFeatures, compatibilityLevel, DataFormat.Default);
                }
                tails[i] = serializer;
            }
        }