private TemplateTranslation overridden(IReadOnlyList <TemplateParameter> parameters, IEnumerable <IEntityInstance> arguments) { var dict = Later.Create(() => this.table.ToDictionary(it => it.Key, it => it.Value)); int i = -1; foreach (IEntityInstance arg in arguments) { ++i; TemplateParameter key = parameters[i]; if (!object.ReferenceEquals(this.table[key], arg)) { dict.Value[key] = arg; } } if (dict.HasValue) { return(new TemplateTranslation(this.parametersProvider, dict.Value)); } else { return(this); } }
public ConstraintMatch ArgumentMatchesParameterConstraints(ComputationContext ctx, EntityInstance closedTemplate, TemplateParameter param) { foreach (IEntityInstance arg in this.elements) { ConstraintMatch match = arg.ArgumentMatchesParameterConstraints(ctx, closedTemplate, param); if (match != ConstraintMatch.Yes) { return(match); } } return(ConstraintMatch.Yes); }
public bool ValidateTypeVariance(ComputationContext ctx, IOwnedNode placement, VarianceMode typeNamePosition) { // Programming in Scala, 2nd ed, p. 399 (all errors are mine) TypeDefinition typedef = this.TargetType; if (typedef.IsTemplateParameter) { TemplateParameter param = typedef.TemplateParameter; TemplateDefinition template = param.EnclosingScope <TemplateDefinition>(); if (placement.EnclosingScopesToRoot().Contains(template)) { bool covariant_in_immutable = param.Variance == VarianceMode.Out && (template.IsFunction() || template.CastType().InstanceOf.MutabilityOfType(ctx) == TypeMutability.ConstAsSource); // don't report errors for covariant types which are used in immutable template types if (!covariant_in_immutable && typeNamePosition.PositionCollides(param.Variance)) { return(false); } } } else { for (int i = 0; i < typedef.Name.Parameters.Count; ++i) { if (!this.TemplateArguments[i].ValidateTypeVariance(ctx, placement, typeNamePosition.Flipped(typedef.Name.Parameters[i].Variance))) { return(false); } } } return(true); }
public bool Translate(TemplateParameter templateParameter, out IEntityInstance instanceArgument) { return(this.table.TryGetValue(templateParameter, out instanceArgument) && instanceArgument != null); }
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); }