Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        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);
            }
        }
Esempio n. 4
0
        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));
        }
Esempio n. 5
0
        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);
        }
Esempio n. 6
0
        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);
        }
Esempio n. 7
0
        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);
        }
Esempio n. 8
0
        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);
        }