Ejemplo n.º 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);
            }
        }
Ejemplo n.º 2
0
        protected EntityInstance createAggregate(ComputationContext ctx, bool hasReference, bool hasPointer,
                                                 IEnumerable <EntityInstance> dereferencedInstances, IEnumerable <FunctionDefinition> members,
                                                 bool partialVirtualTables)
        {
            this.aggregate = TypeBuilder.Create(AutoName.Instance.CreateNew("Aggregate"))
                             .With(members)
                             .SetModifier(EntityModifier.Protocol);
            aggregate.AttachTo(this);
            this.aggregate.Evaluated(ctx, EvaluationCall.AdHocCrossJump);

            EntityInstance aggregate_instance = this.aggregate.InstanceOf;

            foreach (EntityInstance instance in dereferencedInstances)
            {
                EntityInstanceExtension.BuildDuckVirtualTable(ctx, instance, aggregate_instance, allowPartial: partialVirtualTables);
            }

            if (hasReference || hasPointer)
            {
                aggregate_instance = ctx.Env.Reference(aggregate_instance, TypeMutability.None, viaPointer: hasPointer);
            }

            return(aggregate_instance);
        }
Ejemplo n.º 3
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);
        }