Example #1
0
        /// <summary>
        /// Sequentially composes a unification with a dictionary, creating a new unification.
        /// </summary>
        /// <param name="dict">
        /// The dictionary representing another unification to merge.</param>
        /// <returns>
        /// The composed unification (this; <paramref name="dict"/>).
        /// </returns>

        internal ImmutableTypeMap ComposeDict(SmallDictionary <TypeParameterSymbol, TypeWithModifiers> dict)
        {
            // TODO: efficiency
            var dictM = new ImmutableTypeMap(dict);

            var result = new ImmutableTypeMap();

            // We want the resulting mapping to be dict(this(x)).
            // Thus:
            // 1) For all mappings in this (this(x) != x), take our mapping, substitute with dict, and store the resulting mapping;
            // 2) For all mappings in dict, add them back in if they are not already in the new mapping.
            foreach (var ourKey in Mapping.Keys)
            {
                result.Mapping.Add(ourKey, Mapping[ourKey].CustomModifiers.IsEmpty ? dictM.SubstituteType(Mapping[ourKey].AsTypeSymbolOnly()) : Mapping[ourKey]);
            }
            foreach (var theirKey in dict.Keys)
            {
                // This means the other mapping contained this,
                if (result.Mapping.ContainsKey(theirKey))
                {
                    continue;
                }
                result.Mapping.Add(theirKey, dict[theirKey]);
            }

            return(result);
        }
Example #2
0
        /// <summary>
        /// Sequentially composes a unification with a dictionary, creating a new unification.
        /// </summary>
        /// <param name="dict">
        /// The dictionary representing another unification to merge.</param>
        /// <returns>
        /// The composed unification (this; <paramref name="dict"/>).
        /// </returns>

        internal ImmutableTypeMap ComposeDict(SmallDictionary <TypeParameterSymbol, TypeWithModifiers> dict)
        {
            Debug.Assert(IsNormalised, "map should be normalised before composition");

            // TODO: efficiency
            var dictM = new ImmutableTypeMap(dict);

            var result = new ImmutableTypeMap();

            // We want the resulting mapping to be dict(this(x)).
            // Thus:
            // 1) For all mappings in this (this(x) != x), take our mapping, substitute with dict, and store the resulting mapping;
            // 2) For all mappings in dict, add them back in if they are not already in the new mapping.
            foreach (var ourKey in Mapping.Keys)
            {
                result.Mapping.Add(ourKey, Mapping[ourKey].SubstituteType(dictM));
            }
            foreach (var theirKey in dict.Keys)
            {
                if (!result.Mapping.ContainsKey(theirKey))
                {
                    result.Mapping.Add(theirKey, dict[theirKey]);
                }
            }

            Debug.Assert(IsNormalised, "map should be normalised after composition");
            return(result);
        }
Example #3
0
        /// <summary>
        /// Sequentially composes this map with another one, then filters out
        /// the set of additions to the map using the given allowed set.
        /// </summary>
        /// <param name="other">The RHS of the sequential composition.</param>
        /// <param name="allowed">The array of allowed type parameters.</param>
        /// <returns>
        /// The composed map, with the present keys restricted to those either
        /// in this map or in <paramref name="allowed"/>.
        /// </returns>
        public ImmutableTypeMap RestrictedCompose(ImmutableTypeMap other, ImmutableArray <TypeParameterSymbol> allowed)
        {
            // Don't return 'other' if we're empty.
            // 'other' might need restricting.
            if (other.IsEmpty)
            {
                return(this);
            }

            // TODO(MattWindsor91): efficiency: we're creating and disposing
            //     of a lot of intermediate data structures here.
            var unfiltered = Compose(other);

            var rdict = new SmallDictionary <TypeParameterSymbol, TypeWithModifiers>();

            // De-duplicating this is important: SmallDictionary errors
            // on duplicate key insertion.
            var allAllowed = allowed.AddRange(Mapping.Keys).Distinct();

            foreach (var a in allAllowed)
            {
                if (unfiltered.Mapping.ContainsKey(a))
                {
                    rdict.Add(a, unfiltered.Mapping[a]);
                }
            }
            return(new ImmutableTypeMap(rdict));
        }
Example #4
0
 /// <summary>
 /// Sequentially composes two unifications, creating a new unification.
 /// </summary>
 /// <param name="other">The RHS of the sequential composition.</param>
 /// <returns>
 /// The composed unification (this; <paramref name="other"/>).
 /// </returns>
 internal ImmutableTypeMap Compose(ImmutableTypeMap other)
 {
     if (IsEmpty)
     {
         return(other);
     }
     if (other.IsEmpty)
     {
         return(this);
     }
     return(ComposeDict(other.Mapping));
 }
Example #5
0
 /// <summary>
 /// Sequentially composes two unifications, creating a new unification.
 /// </summary>
 /// <param name="other">
 /// The RHS of the sequential composition.</param>
 /// <returns>
 /// The composed unification (this; <paramref name="other"/>).
 /// </returns>
 internal ImmutableTypeMap Compose(ImmutableTypeMap other) => ComposeDict(other.Mapping);