Esempio n. 1
0
        /// <summary>
        /// Creates a qualifier from a given input qualifier such that the resulting qualifier respects target qualifier space.
        /// </summary>
        public bool TryCreateQualifierForQualifierSpace(
            PathTable pathTable,
            LoggingContext loggingContext,
            QualifierId qualifierId,
            QualifierSpaceId qualifierSpaceId,
            bool useDefaultsForCoercion,
            out QualifierId resultingQualifierId,
            out UnsupportedQualifierValue error)
        {
            Contract.RequiresNotNull(pathTable);
            Contract.RequiresNotNull(loggingContext);
#if DEBUG
            Contract.Requires(IsValidQualifierId(qualifierId));
            Contract.Requires(qualifierSpaceId.IsValid);
            Contract.Requires(IsValidQualifierSpaceId(qualifierSpaceId), "Id " + qualifierSpaceId.Id + " is not valid.");
#endif

            Qualifier      qualifier      = GetQualifier(qualifierId);
            QualifierSpace qualifierSpace = GetQualifierSpace(qualifierSpaceId);
            Qualifier      resultingQualifier;

            bool success = qualifierSpace.TryCreateQualifierForQualifierSpace(
                StringTable,
                pathTable,
                loggingContext,
                qualifier,
                out resultingQualifier,
                out error,
                useDefaultsForCoercion);
            resultingQualifierId = success ? GetOrAddQualifier(resultingQualifier) : EmptyQualifierId;

            return(success);
        }
Esempio n. 2
0
        /// <summary>
        /// Creates a qualifier from a given input qualifier such that the resulting qualifier respects this qualifier space.
        /// </summary>
        internal bool TryCreateQualifierForQualifierSpace(
            StringTable stringTable,
            PathTable pathTable,
            LoggingContext loggingContext,
            Qualifier currentQualifier,
            out Qualifier qualifier,
            out UnsupportedQualifierValue error,
            bool useDefaults)
        {
            Contract.Requires(stringTable != null);
            Contract.Requires(pathTable != null);
            Contract.Requires(loggingContext != null);

            StringId[] keys;
            StringId[] values;
            currentQualifier.GetInternalKeyValueArrays(out keys, out values);

            var targetKeys   = new StringId[m_keys.Length];
            var targetValues = new StringId[m_keys.Length];

            int qIndex = 0;
            int sIndex = 0;

            while (sIndex < m_keys.Length)
            {
                var sKey = m_keys[sIndex];

                if (qIndex < keys.Length && keys[qIndex] == sKey)
                {
                    var qValue = values[qIndex];
                    if (m_valueValues[sIndex].Contains(qValue))
                    {
                        targetKeys[sIndex]   = keys[qIndex];
                        targetValues[sIndex] = qValue;

                        qIndex++;
                        sIndex++;
                    }
                    else
                    {
                        error = new UnsupportedQualifierValue
                        {
                            QualifierKey = sKey.ToString(stringTable),
                            InvalidValue = qValue.ToString(stringTable),
                            LegalValues  = string.Join(", ", m_valueValues[sIndex].Select(id => id.ToString(stringTable))),
                        };

                        qualifier = Qualifier.Empty;
                        return(false);
                    }
                }
                else
                {
                    // Check if we have any key from the currentQualifier left. If not, we'll 'trick' the compare below be a 'missing'
                    // value we can treat it to insert the default value for the remaining space keys
                    var compare = qIndex < keys.Length ? stringTable.OrdinalComparer.Compare(keys[qIndex], sKey) : 1;
                    Contract.Assume(compare != 0, "expected above equals to handle that case");

                    if (compare < 0)
                    {
                        // Given that the lists are sorted and the qualifier key is less than the space key, it means that key is not in the target space.
                        // so we can skip it.
                        qIndex++;
                    }
                    else
                    {
                        if (useDefaults == false)
                        {
                            qualifier = Qualifier.Empty;

                            // var lineInfo = location.Value.ToLogLocation(pathTable);
                            // TODO: Consider adding a more specific exception for the no defaults case
                            error = new UnsupportedQualifierValue
                            {
                                // Location = lineInfo,
                                QualifierKey = sKey.ToString(stringTable),
                                InvalidValue = string.Empty,
                                LegalValues  = string.Join(", ", m_valueValues[sIndex].Select(id => id.ToString(stringTable))),
                            };

                            return(false);
                        }

                        // It is larger, so we need to add the default value of the space to the target if enabled.
                        targetKeys[sIndex]   = sKey;
                        targetValues[sIndex] = m_defaults[sIndex];

                        sIndex++;
                    }
                }
            }

            qualifier = new Qualifier(targetKeys, targetValues);
            error     = default(UnsupportedQualifierValue);

            return(true);
        }