Example #1
0
        private static bool templateMatches(ComputationContext ctx, EntityInstance input,
                                            EntityInstance target, TypeMatching matching,
                                            out TypeMatch failMatch)
        {
            if (input.IsJoker || target.IsJoker)
            {
                failMatch = TypeMatch.Same;
                return(true);
            }

            bool matches = strictTemplateMatches(ctx, input, target, matching, out failMatch);

            TypeDefinition target_type = target.TargetType;

            if (matches || (!(matching.DuckTyping && target_type.IsInterface) && !target_type.IsProtocol))
            {
                return(matches);
            }

            VirtualTable vtable = EntityInstanceExtension.BuildDuckVirtualTable(ctx, input, target, allowPartial: false);

            if (vtable == null)
            {
                return(false);
            }
            else
            {
                failMatch = TypeMatch.Same;
                return(true);
            }
        }
Example #2
0
        internal void OverrideWith(VirtualTable table)
        {
            if (table == null)
            {
                return;
            }

            foreach (KeyValuePair <FunctionDefinition, FunctionDefinition> entry in table.baseDerivedMapping)
            {
                this.Update(entry.Key, entry.Value);
            }
        }
Example #3
0
 public bool TryGetDuckVirtualTable(EntityInstance target, out VirtualTable vtable)
 {
     return(this.duckVirtualTables.TryGetValue(target.core, out vtable));
 }
Example #4
0
            internal void AddDuckVirtualTable(ComputationContext ctx, EntityInstance target, VirtualTable vtable)
            {
                if (vtable == null)
                {
                    throw new Exception("Internal error");
                }

                this.duckVirtualTables.Add(target.core, vtable);
            }
Example #5
0
        public ConstraintMatch ArgumentMatchesParameterConstraints(ComputationContext ctx, EntityInstance closedTemplate,
                                                                   TemplateParameter param)
        {
            if (this.TargetsTemplateParameter && this.TemplateParameterTarget == param)
            {
                return(ConstraintMatch.Yes);
            }

            TypeMutability arg_mutability = this.SurfaceMutabilityOfType(ctx);

            if (param.Constraint.Modifier.HasConst &&
                arg_mutability != TypeMutability.ForceConst && arg_mutability != TypeMutability.ConstAsSource)
            {
                return(ConstraintMatch.MutabilityViolation);
            }
            else if (param.Constraint.Modifier.HasMutable && arg_mutability != TypeMutability.ForceMutable)
            {
                return(ConstraintMatch.MutabilityViolation);
            }
            else if (param.Constraint.Modifier.HasReassignable && !arg_mutability.HasFlag(TypeMutability.Reassignable))
            {
                return(ConstraintMatch.AssignabilityViolation);
            }

            // 'inherits' part of constraint
            foreach (EntityInstance constraint_inherits in param.Constraint.TranslateInherits(closedTemplate))
            {
                TypeMatch match = TypeMatcher.Matches(ctx, this, constraint_inherits,
                                                      TypeMatching.Create(ctx.Env.Options.InterfaceDuckTyping, allowSlicing: true));
                if (match.IsMismatch())
                {
                    return(ConstraintMatch.InheritsViolation);
                }
            }

            {
                VirtualTable vtable = EntityInstanceExtension.BuildDuckVirtualTable(ctx, this, param.AssociatedType.InstanceOf,
                                                                                    allowPartial: false);
                if (vtable == null)
                {
                    return(ConstraintMatch.MissingFunction);
                }
            }


            // 'base-of' part of constraint
            IEnumerable <IEntityInstance> arg_bases = (this.TargetsTemplateParameter
                ? this.TargetType.TemplateParameter.Constraint.TranslateBaseOf(closedTemplate)
                : Enumerable.Empty <EntityInstance>()
                                                       )
                                                      .Concat(this);

            foreach (EntityInstance constraint_base in param.Constraint.TranslateBaseOf(closedTemplate))
            {
                if (!arg_bases.Any(it => !constraint_base.MatchesTarget(ctx, it, TypeMatching.Create(ctx.Env.Options.InterfaceDuckTyping, allowSlicing: true))
                                   .IsMismatch()))
                {
                    return(ConstraintMatch.BaseViolation);
                }
            }

            return(ConstraintMatch.Yes);
        }
Example #6
0
 internal void AddDuckVirtualTable(ComputationContext ctx, EntityInstance target, VirtualTable vtable)
 {
     this.core.AddDuckVirtualTable(ctx, target, vtable);
 }