private bool computeLowestCommonAncestor(ComputationContext ctx, ref IEntityInstance eval, ref IEntityInstance aggregate) { if (!TypeMatcher.LowestCommonAncestor(ctx, eval, Next.Evaluation.Components, out eval)) { return(false); } else if (!TypeMatcher.LowestCommonAncestor(ctx, aggregate, Next.Evaluation.Aggregate, out aggregate)) { return(false); } else { foreach (IEvaluable part in new IEvaluable[] { Body, Next }) { if (part.Evaluation.Components.MatchesTarget(ctx, eval, TypeMatching.Create(ctx.Env.Options.InterfaceDuckTyping, allowSlicing: false)).IsMismatch()) { return(false); } if (part.Evaluation.Aggregate.MatchesTarget(ctx, aggregate, TypeMatching.Create(ctx.Env.Options.InterfaceDuckTyping, allowSlicing: false)).IsMismatch()) { return(false); } } } return(true); }
public static bool MatchTypes(ComputationContext ctx, IEntityInstance lhsTypeInstance, IEntityInstance rhsTypeInstance) { TypeMatch lhs_rhs_match = lhsTypeInstance.MatchesTarget(ctx, rhsTypeInstance, TypeMatching.Create(duckTyping: false, allowSlicing: true).WithIgnoredMutability(true)); return(lhs_rhs_match.Passed); }
internal void InferResultType(ComputationContext ctx) { if (!this.resultTypeCandidates.Any()) // no returns { setResultParameter(ctx.Env.UnitType.InstanceOf.NameOf); } else { IEntityInstance common = this.resultTypeCandidates.First(); foreach (IEntityInstance candidate in this.resultTypeCandidates.Skip(1)) { if (!TypeMatcher.LowestCommonAncestor(ctx, common, candidate, out common)) { ctx.AddError(ErrorCode.CannotInferResultType, this); setResultParameter(Environment.JokerInstance.NameOf); return; } } foreach (IEntityInstance candidate in this.resultTypeCandidates) { // it is tempting to allowing conversions here, but it would mean that we have back to all "returns" // to apply such conversions, besides such fluent result type is a bit of a stretch TypeMatch match = candidate.MatchesTarget(ctx, common, TypeMatching.Create(ctx.Env.Options.InterfaceDuckTyping, allowSlicing: false)); if (match != TypeMatch.Same && match != TypeMatch.Substitute) { ctx.AddError(ErrorCode.CannotInferResultType, this); setResultParameter(Environment.JokerInstance.NameOf); return; } } setResultParameter(common.NameOf); } }
public static bool IsCopyInitConstructor(this FunctionDefinition @this, ComputationContext ctx) { if ([email protected]() || @this.Parameters.Count != 1) { return(false); } IEntityInstance param_type = @this.Parameters.Single().TypeName.Evaluation.Components; EntityInstance containing_type = @this.ContainingType().InstanceOf; TypeMatch match = param_type.MatchesTarget(ctx, containing_type, TypeMatching.Create(duckTyping: false, allowSlicing: false).WithIgnoredMutability(true)); return(match.HasFlag(TypeMatch.Same)); }
public IErrorReporter InheritanceMatching() { NameResolver resolver = null; foreach (var mutability in Options.AllMutabilityModes) { var env = Language.Environment.Create(new Options() { }.SetMutability(mutability)); var root_ns = env.Root; var system_ns = env.SystemNamespace; var unrelated_type = system_ns.AddBuilder(TypeBuilder.Create(NameDefinition.Create("Separate"))); var abc_type = system_ns.AddBuilder(TypeBuilder.Create(NameDefinition.Create("ABC"))); var derived_type = system_ns.AddBuilder(TypeBuilder.Create(NameDefinition.Create("Deriv")) .Parents(NameReference.Create("ABC"))); var foo_type = system_ns.AddBuilder(TypeBuilder.Create(NameDefinition.Create("Foo", "V", VarianceMode.Out)) .Parents(NameReference.Create("ABC"))); var tuple_type = system_ns.AddBuilder(TypeBuilder.Create(NameDefinition.Create("Tuple", "T", VarianceMode.None)) .Parents(NameReference.Create("Foo", NameReference.Create("T")))); var separate_ref = system_ns.AddNode(NameReference.Create("Separate")); var abc_ref = system_ns.AddNode(NameReference.Create("ABC")); var deriv_ref = system_ns.AddNode(NameReference.Create("Deriv")); var tuple_deriv_ref = system_ns.AddNode(NameReference.Create("Tuple", NameReference.Create("Deriv"))); var foo_abc_ref = system_ns.AddNode(NameReference.Create("Foo", NameReference.Create("ABC"))); var tuple_abc_ref = system_ns.AddNode(NameReference.Create("Tuple", NameReference.Create("ABC"))); var foo_deriv_ref = system_ns.AddNode(NameReference.Create("Foo", NameReference.Create("Deriv"))); resolver = NameResolver.Create(env); Assert.AreNotEqual(TypeMatch.Same, separate_ref.Binding.Match.Instance.MatchesTarget(resolver.Context, abc_ref.Binding.Match.Instance, TypeMatching.Create(env.Options.InterfaceDuckTyping, allowSlicing: true))); Assert.AreEqual(TypeMatch.Substitute, deriv_ref.Binding.Match.Instance.MatchesTarget(resolver.Context, abc_ref.Binding.Match.Instance, TypeMatching.Create(env.Options.InterfaceDuckTyping, allowSlicing: true))); Assert.AreEqual(TypeMatch.Substitute, tuple_deriv_ref.Binding.Match.Instance.MatchesTarget(resolver.Context, foo_abc_ref.Binding.Match.Instance, TypeMatching.Create(env.Options.InterfaceDuckTyping, allowSlicing: true))); TypeMatch match = tuple_abc_ref.Binding.Match.Instance.MatchesTarget(resolver.Context, foo_deriv_ref.Binding.Match.Instance, TypeMatching.Create(env.Options.InterfaceDuckTyping, allowSlicing: true)); Assert.AreNotEqual(TypeMatch.Same, match); Assert.AreNotEqual(TypeMatch.Substitute, match); } return(resolver); }
public static bool IsDerivedOf(ComputationContext ctx, FunctionDefinition derivedFunc, FunctionDefinition baseFunc, EntityInstance baseTemplate) { if (derivedFunc.IsPropertyAccessor(out Property derived_prop)) { if (baseFunc.IsPropertyAccessor(out Property base_prop)) { // properties have to much and name (kind) of the accessor if (!EntityNameArityComparer.Instance.Equals(derived_prop.Name, base_prop.Name) || !EntityNameArityComparer.Instance.Equals(derivedFunc.Name, baseFunc.Name)) { return(false); } } // property-getters can override regular methods else if (derived_prop.Getter != derivedFunc || !EntityNameArityComparer.Instance.Equals(derived_prop.Name, baseFunc.Name)) { return(false); } } // todo: we have to check constraints as well else if (!EntityNameArityComparer.Instance.Equals(derivedFunc.Name, baseFunc.Name)) { return(false); } foreach (Tuple <TemplateParameter, TemplateParameter> param_pair in derivedFunc.Name.Parameters .SyncZip(baseFunc.Name.Parameters)) { if (!TemplateParameterExtension.IsSame(param_pair.Item1, param_pair.Item2, baseTemplate)) { return(false); } } { IEntityInstance base_result_type = baseFunc.ResultTypeName.Evaluation.Components.TranslateThrough(baseTemplate); TypeMatch match = derivedFunc.ResultTypeName.Evaluation.Components.MatchesTarget(ctx, base_result_type, TypeMatching.Create(ctx.Env.Options.InterfaceDuckTyping, allowSlicing: false)); if (match != TypeMatch.Same && match != TypeMatch.Substitute) { return(false); } } if (derivedFunc.Parameters.Count != baseFunc.Parameters.Count) { return(false); } foreach (Tuple <FunctionParameter, FunctionParameter> param_pair in derivedFunc.Parameters.SyncZip(baseFunc.Parameters)) { if (!FunctionParameterExtension.IsDerivedOf(ctx, param_pair.Item1, param_pair.Item2, baseTemplate)) { return(false); } } return(true); }
public IErrorReporter UnionMatching() { NameResolver resolver = null; foreach (var mutability in Options.AllMutabilityModes) { var env = Language.Environment.Create(new Options() { }.SetMutability(mutability)); var root_ns = env.Root; var system_ns = env.SystemNamespace; root_ns.AddBuilder(TypeBuilder.Create(NameDefinition.Create("Separate"))); root_ns.AddBuilder(TypeBuilder.Create(NameDefinition.Create("ABC"))); root_ns.AddBuilder(TypeBuilder.Create(NameDefinition.Create("Deriv")) .Parents(NameReference.Create("ABC"))); root_ns.AddBuilder(TypeBuilder.Create(NameDefinition.Create("Deriz")) .Parents(NameReference.Create("Deriv"))); root_ns.AddBuilder(TypeBuilder.Create(NameDefinition.Create("qwerty")) .Parents(NameReference.Create("ABC"))); root_ns.AddBuilder(TypeBuilder.Create(NameDefinition.Create("sink")) .Parents(NameReference.Create("qwerty"), NameReference.Create("Separate"))); var separate_deriv_union = root_ns.AddNode(NameReferenceUnion.Create(NameReference.Create("Separate"), NameReference.Create("Deriv"))); var separate_deriz_union = root_ns.AddNode(NameReferenceUnion.Create(NameReference.Create("Separate"), NameReference.Create("Deriz"))); var separate_abc_union = root_ns.AddNode(NameReferenceUnion.Create(NameReference.Create("Separate"), NameReference.Create("ABC"))); var sink_union = root_ns.AddNode(NameReferenceUnion.Create(NameReference.Create("sink"))); var sink_deriv_union = root_ns.AddNode(NameReferenceUnion.Create(NameReference.Create("sink"), NameReference.Create("Deriv"))); resolver = NameResolver.Create(env); Assert.AreEqual(TypeMatch.Substitute, separate_deriz_union.Evaluation.Components.MatchesTarget(resolver.Context, separate_deriv_union.Evaluation.Components, TypeMatching.Create(env.Options.InterfaceDuckTyping, allowSlicing: true))); Assert.AreEqual(TypeMatch.Substitute, sink_union.Evaluation.Components.MatchesTarget(resolver.Context, separate_abc_union.Evaluation.Components, TypeMatching.Create(env.Options.InterfaceDuckTyping, allowSlicing: true))); TypeMatch match = sink_deriv_union.Evaluation.Components.MatchesTarget(resolver.Context, separate_deriz_union.Evaluation.Components, TypeMatching.Create(env.Options.InterfaceDuckTyping, allowSlicing: true)); Assert.AreNotEqual(TypeMatch.Same, match); Assert.AreNotEqual(TypeMatch.Substitute, match); } return(resolver); }
public static bool DataTransfer(this IEvaluable @this, ComputationContext ctx, ref IExpression source, IEntityInstance targetTypeName, bool ignoreMutability = false) { if (source == null) { return(true); } IEntityInstance src_type = source.Evaluation.Components; TypeMatch match = src_type.MatchesTarget(ctx, targetTypeName, TypeMatching.Create(ctx.Env.Options.InterfaceDuckTyping, allowSlicing: false) .WithIgnoredMutability(ignoreMutability) .AllowedLifetimeChecking(true)); if (match.HasFlag(TypeMatch.Attachment)) { match ^= TypeMatch.Attachment; } if (match == TypeMatch.No) { ctx.ErrorManager.AddError(ErrorCode.TypeMismatch, source); return(false); } else if (match == TypeMatch.Lifetime) { ctx.ErrorManager.AddError(ErrorCode.EscapingReference, source); return(false); } else if (match == TypeMatch.InConversion) { source.DetachFrom(@this); source = ExpressionFactory.StackConstructor((targetTypeName as EntityInstance).NameOf, FunctionArgument.Create(source)); source.AttachTo(@this); TypeMatch m = source.Evaluated(ctx, EvaluationCall.AdHocCrossJump).MatchesTarget(ctx, targetTypeName, TypeMatching.Create(ctx.Env.Options.InterfaceDuckTyping, allowSlicing: false)); if (m != TypeMatch.Same && m != TypeMatch.Substitute) { throw new Exception("Internal error"); } } else if (match.HasFlag(TypeMatch.ImplicitReference)) { match ^= TypeMatch.ImplicitReference; if (match != TypeMatch.Substitute && match != TypeMatch.Same) { throw new NotImplementedException(); } source.DetachFrom(@this); source = AddressOf.CreateReference(source); source.AttachTo(@this); IEntityInstance source_eval = source.Evaluated(ctx, EvaluationCall.AdHocCrossJump); TypeMatch m = source_eval.MatchesTarget(ctx, targetTypeName, TypeMatching.Create(ctx.Env.Options.InterfaceDuckTyping, allowSlicing: true)); if (m != TypeMatch.Same && m != TypeMatch.Substitute) { throw new Exception($"Internal error: matching result {m}"); } } else if (match == TypeMatch.OutConversion) { source.DetachFrom(@this); source = FunctionCall.ConvCall(source, (targetTypeName as EntityInstance).NameOf); source.AttachTo(@this); TypeMatch m = source.Evaluated(ctx, EvaluationCall.AdHocCrossJump).MatchesTarget(ctx, targetTypeName, TypeMatching.Create(ctx.Env.Options.InterfaceDuckTyping, allowSlicing: false)); if (m != TypeMatch.Same && m != TypeMatch.Substitute) { throw new Exception("Internal error"); } } else if (match.HasFlag(TypeMatch.AutoDereference)) { source.DereferencedCount_LEGACY = match.Dereferences; @this.Cast <IExpression>().DereferencingCount = match.Dereferences; match ^= TypeMatch.AutoDereference; if (match != TypeMatch.Substitute && match != TypeMatch.Same) { throw new NotImplementedException(); } } else if (match != TypeMatch.Same && match != TypeMatch.Substitute) { throw new NotImplementedException(); } return(true); }