Esempio n. 1
0
 public EntityInstance GetInstance(TypeMutability overrideMutability,
                                   TemplateTranslation translation, Lifetime lifetime)
 {
     return(this.instancesCache.GetInstance(overrideMutability, translation, lifetime));
 }
Esempio n. 2
0
 public NameReference CreateNameReference(IExpression prefix, TypeMutability mutability)
 {
     return(NameReference.Create(mutability, prefix, this.Name,
                                 this.Parameters.Select(it => NameReference.Create(it.Name)), target: null, isLocal: false));
 }
Esempio n. 3
0
 public static IEntityInstance Rebuild(this IEntityInstance instance, ComputationContext ctx, TypeMutability mutability, bool deep = true)
 {
     return(instance.Map(elem => elem.Rebuild(ctx, mutability, deep)));
 }
Esempio n. 4
0
        public void Validate(ComputationContext ctx)
        {
            if (this.Resolution == null)
            {
                return;
            }

            FunctionDefinition enclosing_func = this.EnclosingScope <FunctionDefinition>();

            if (this.Resolution.TargetFunction.Modifier.IsPolymorphic &&
                enclosing_func != null && enclosing_func.IsAnyConstructor() &&
                !enclosing_func.ContainingType().Modifier.IsSealed)
            {
                ctx.AddError(ErrorCode.VirtualCallFromConstructor, this);
            }

            if (this.mode != CallMode.Constructor && this.Resolution.TargetFunction.IsAnyConstructor())
            {
                ctx.AddError(ErrorCode.ConstructorCallFromFunctionBody, this);
            }

            {
                bool is_recall = isRecall(out FunctionDefinition curr_func, out FunctionDefinition binding_func);
                if (!ctx.Env.Options.AllowNamedSelf && binding_func != null)
                {
                    if (this.Name.Name != NameFactory.RecurFunctionName && is_recall)
                    {
                        ctx.ErrorManager.AddError(ErrorCode.NamedRecursiveFunctionReference, this.Name);
                    }
                    else if (!this.Name.IsSuperReference && curr_func != null)
                    {
                        FunctionDefinition super_func = curr_func.TryGetSuperFunction(ctx);
                        if (super_func == binding_func)
                        {
                            ctx.ErrorManager.AddError(ErrorCode.NamedRecursiveFunctionReference, this.Name);
                        }
                    }
                }
            }

            {
                if (this.Name.TargetsCurrentInstanceMember(out IMember member))
                {
                    FunctionDefinition callee = member.CastFunction();
                    FunctionDefinition func   = this.EnclosingScope <FunctionDefinition>();
                    if (!func.Modifier.HasMutable && !func.IsAnyConstructor() && callee.Modifier.HasMutable)
                    {
                        ctx.AddError(ErrorCode.CallingMutableFromImmutableMethod, this);
                    }
                }
            }

            if (this.Resolution.MetaThisArgument != null)
            {
                // we cannot call mutable methods on neutral instance as well, because in such case we could
                // pass const instance (of mutable type) as neutral instance (aliasing const instance)
                // and then call mutable method making "const" guarantee invalid

                TypeMutability this_mutability = this.Resolution.MetaThisArgument.Expression.Evaluation.Components.MutabilityOfType(ctx);
                if (!this_mutability.HasFlag(TypeMutability.ForceMutable) && this.Resolution.TargetFunction.Modifier.HasMutable)
                {
                    ctx.AddError(ErrorCode.AlteringNonMutableInstance, this);
                }
            }


            if (this.Resolution.TargetFunction.Modifier.HasHeapOnly)
            {
                FunctionDefinition func = this.EnclosingScope <FunctionDefinition>();
                if ((this.Name.Prefix != null && !ctx.Env.IsPointerOfType(this.Name.Prefix.Evaluation.Components)) ||
                    (this.Name.Prefix == null && !func.Modifier.HasHeapOnly))
                {
                    ctx.AddError(ErrorCode.CallingHeapFunctionWithValue, this);
                }
            }
        }
Esempio n. 5
0
        private static TypeDefinition buildTypeOfReference(ComputationContext ctx,
                                                           NameReference funcReference, IExpression thisObject)
        {
            if (funcReference.Owner != null)
            {
                throw new Exception("Detach it first.");
            }

            const string meta_this = "mThis";

            FunctionDefinition function = funcReference.Binding.Match.Instance.Target.CastFunction();

            FunctionDefinition cons;
            NameReference      func_field_ref;

            if (thisObject != null)
            {
                cons = FunctionDefinition.CreateInitConstructor(EntityModifier.None,
                                                                new[] { FunctionParameter.Create(meta_this, thisObject.Evaluation.Components.NameOf) },
                                                                Block.CreateStatement(
                                                                    new[] {
                    Assignment.CreateStatement(NameReference.Create(NameFactory.ThisVariableName, meta_this),
                                               NameReference.Create(meta_this)),
                }));

                func_field_ref = NameReference.Create(NameFactory.ThisVariableName, meta_this);
            }
            else
            {
                func_field_ref = null;
                cons           = null;
            }

            IEnumerable <FunctionParameter> trans_parameters = function.Parameters.Select(pit =>
                                                                                          FunctionParameter.Create(pit.Name.Name, pit.TypeName.Evaluated(ctx, EvaluationCall.AdHocCrossJump)
                                                                                                                   .TranslateThrough(funcReference.Binding.Match.Instance).NameOf));
            FunctionDefinition invoke = FunctionBuilder.Create(NameFactory.LambdaInvoke, ExpressionReadMode.ReadRequired,
                                                               function.ResultTypeName,
                                                               Block.CreateStatement(new[] {
                Return.Create(FunctionCall.Create(
                                  NameReference.Create(func_field_ref, funcReference.Name,
                                                       funcReference.TemplateArguments.Select(it => it.TypeName).ToArray()),
                                  function.Parameters.Select(it => FunctionArgument.Create(NameReference.Create(it.Name.Name))).ToArray()))
            }))
                                        .SetModifier(EntityModifier.Override)
                                        .Parameters(trans_parameters.ToArray());


            TypeBuilder closure_builder = TypeBuilder.Create(NameDefinition.Create(AutoName.Instance.CreateNew("Closure")))
                                          .With(invoke)
                                          .Parents(invoke.CreateFunctionInterface());

            if (thisObject != null)
            {
                VariableDeclaration this_field = VariableDeclaration.CreateStatement(meta_this,
                                                                                     thisObject.Evaluation.Components.NameOf, Undef.Create());
                closure_builder
                .With(cons)
                .With(this_field);

                TypeMutability mutability = thisObject.Evaluation.Components.MutabilityOfType(ctx);
                if (mutability == TypeMutability.ForceMutable)
                {
                    closure_builder.SetModifier(EntityModifier.Mutable);
                }
                else if (mutability != TypeMutability.ConstAsSource)
                {
                    throw new NotImplementedException();
                }
            }

            return(closure_builder);
        }
Esempio n. 6
0
 public static NameReference SelfNameReference(TypeMutability mutability = TypeMutability.None)
 {
     return(NameReference.Create(mutability, SelfTypeTypeName));
 }
Esempio n. 7
0
 public static NameReference Create(TypeMutability overrideMutability, string name, params INameReference[] arguments)
 {
     return(Create(overrideMutability, null, name, arguments));
 }
Esempio n. 8
0
 internal static Alloc Create(NameReference innerTypename, Memory memory, TypeMutability mutability = TypeMutability.None)
 {
     return(new Alloc(innerTypename, memory, mutability));
 }
Esempio n. 9
0
 public static IExpression HeapConstructor(NameReference innerTypeName, TypeMutability mutability, params FunctionArgument[] arguments)
 {
     return(ConstructorCall.HeapConstructor(mutability, innerTypeName, arguments).Build());
 }
Esempio n. 10
0
        internal EntityInstance Build(IEnumerable <IEntityInstance> templateArguments, TypeMutability overrideMutability)
        {
            TemplateTranslation combined = this.Translation.Overridden(templateArguments);

            return(this.Target.GetInstance(overrideMutability, combined, this.Lifetime));
        }
Esempio n. 11
0
 internal EntityInstance Build(IEnumerable <TemplateArgument> templateArguments, TypeMutability overrideMutability)
 {
     return(Build(templateArguments.Select(it => it.TypeName.Evaluation.Components), overrideMutability));
 }
Esempio n. 12
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);
        }
Esempio n. 13
0
        public override void Validate(ComputationContext ctx)
        {
            base.Validate(ctx);

            if (this.Modifier.HasTrait)
            {
                if (!this.Name.Parameters.Any())
                {
                    ctx.AddError(ErrorCode.NonGenericTrait, this);
                }
                else
                {
                    if (!this.Constraints.Any())
                    {
                        ctx.AddError(ErrorCode.UnconstrainedTrait, this);
                    }

                    TypeDefinition host_type = AssociatedHost;
                    if (host_type == null)
                    {
                        ctx.AddError(ErrorCode.MissingHostTypeForTrait, this);
                    }
                }
            }

            if (this.Modifier.HasAssociatedReference)
            {
                if (!this.Modifier.IsSealed)
                {
                    ctx.AddError(ErrorCode.AssociatedReferenceRequiresSealedType, this.Modifier);
                }

                {
                    IEnumerable <FunctionDefinition> constructors = this.NestedFunctions.Where(it => it.IsInitConstructor());

                    foreach (FunctionDefinition cons in constructors.Skip(1))
                    {
                        ctx.AddError(ErrorCode.AssociatedReferenceRequiresSingleConstructor, cons);
                    }

                    FunctionDefinition primary_cons = constructors.First();
                    if (primary_cons.Parameters.Count != 1)
                    {
                        ctx.AddError(ErrorCode.AssociatedReferenceRequiresSingleParameter, primary_cons);
                    }
                    else
                    {
                        FunctionParameter cons_param = primary_cons.Parameters.Single();
                        if (!ctx.Env.IsReferenceOfType(cons_param.TypeName.Evaluation.Components))
                        {
                            ctx.AddError(ErrorCode.AssociatedReferenceRequiresReferenceParameter, cons_param.TypeName);
                        }
                        else if (cons_param.IsVariadic)
                        {
                            ctx.AddError(ErrorCode.AssociatedReferenceRequiresNonVariadicParameter, cons_param);
                        }
                        else if (cons_param.IsOptional)
                        {
                            ctx.AddError(ErrorCode.AssociatedReferenceRequiresNonOptionalParameter, cons_param);
                        }
                    }
                }

                {
                    IEnumerable <VariableDeclaration> ref_fields = this.NestedFields
                                                                   .Where(it => ctx.Env.IsReferenceOfType(it.Evaluation.Components));

                    foreach (VariableDeclaration decl in ref_fields.Skip(1))
                    {
                        ctx.AddError(ErrorCode.AssociatedReferenceRequiresSingleReferenceField, decl);
                    }
                }
            }

            {
                IEnumerable <VariableDeclaration> ref_fields = this.NestedFields
                                                               .Where(it => ctx.Env.IsReferenceOfType(it.Evaluation.Components));

                VariableDeclaration primary = ref_fields.FirstOrDefault();
                if (primary != null && primary.IsReassignable(ctx))
                {
                    ctx.AddError(ErrorCode.ReferenceFieldCannotBeReassignable, primary);
                }
            }

            foreach (NameReference parent in this.ParentNames.Skip(1))
            {
                if (parent.Evaluation.Components.Cast <EntityInstance>().TargetType.IsTypeImplementation)
                {
                    ctx.AddError(ErrorCode.TypeImplementationAsSecondaryParent, parent);
                }
            }

            {
                TypeDefinition primary_parent = this.Inheritance.GetTypeImplementationParent()?.TargetType;
                if (primary_parent != null)
                {
                    if (this.Modifier.HasEnum != primary_parent.Modifier.HasEnum)
                    {
                        ctx.AddError(ErrorCode.EnumCrossInheritance, this);
                    }

                    if (this.Modifier.HasTrait)
                    {
                        ctx.AddError(ErrorCode.TraitInheritingTypeImplementation, this.ParentNames.First());
                    }
                }
            }

            if (!this.Modifier.IsAbstract)
            {
                foreach (FunctionDefinition func in this.AllNestedFunctions)
                {
                    if (func.Modifier.HasAbstract)
                    {
                        ctx.AddError(ErrorCode.NonAbstractTypeWithAbstractMethod, func);
                    }
                    else if (func.Modifier.HasBase && this.Modifier.IsSealed)
                    {
                        ctx.AddError(ErrorCode.SealedTypeWithBaseMethod, func);
                    }
                }
            }

            {
                TypeMutability current_mutability = this.InstanceOf.MutabilityOfType(ctx);
                if (current_mutability != TypeMutability.ForceMutable)
                {
                    // the above check is more than checking just a flag
                    // for template types the mutability depends on parameter constraints
                    foreach (NameReference parent in this.ParentNames)
                    {
                        TypeMutability parent_mutability = parent.Evaluation.Components.MutabilityOfType(ctx);
                        if (parent_mutability == TypeMutability.ForceMutable)
                        {
                            ctx.AddError(ErrorCode.InheritanceMutabilityViolation, parent);
                        }
                    }
                }
            }

            if (!this.Modifier.HasMutable)
            {
                foreach (VariableDeclaration field in this.AllNestedFields)
                {
                    if (field.Modifier.HasReassignable)
                    {
                        ctx.AddError(ErrorCode.MutableFieldInImmutableType, field);
                    }
                    else
                    {
                        TypeMutability field_eval_mutability = field.Evaluation.Components.MutabilityOfType(ctx);
                        if (!field_eval_mutability.HasFlag(TypeMutability.ConstAsSource) &&
                            !field_eval_mutability.HasFlag(TypeMutability.GenericUnknownMutability) &&
                            !field_eval_mutability.HasFlag(TypeMutability.ForceConst))
                        {
                            ctx.AddError(ErrorCode.MutableFieldInImmutableType, field);
                        }
                    }
                }
                foreach (FunctionDefinition func in this.NestedFunctions
                         .Where(it => it.Modifier.HasMutable))
                {
                    ctx.AddError(ErrorCode.MutableFunctionInImmutableType, func);
                }

                foreach (Property property in this.NestedProperties
                         .Where(it => it.Setter != null))
                {
                    ctx.AddError(ErrorCode.PropertySetterInImmutableType, property);
                }
            }
        }
Esempio n. 14
0
 public NameReference CreateTypeNameReference(TypeMutability mutability = TypeMutability.None)
 {
     return(this.name.CreateNameReference(prefix: null, mutability: mutability));
 }
Esempio n. 15
0
 internal EntityInstance GetInstance(IEntity entity,
                                     TypeMutability overrideMutability, TemplateTranslation translation, Lifetime lifetime)
 {
     if (!this.cache.TryGetValue(lifetime, out EntityInstance[] inner_cache))
Esempio n. 16
0
 public static ConstructorCall HeapConstructor(string innerTypeName, TypeMutability mutability, params IExpression[] arguments)
 {
     return(HeapConstructor(mutability, NameReference.Create(innerTypeName), arguments));
 }
Esempio n. 17
0
 public static NameReference SizeNameReference(TypeMutability mutability = TypeMutability.None)
 {
     return(NameReference.Create(mutability, NameReference.Root, SizeTypeName));
 }
Esempio n. 18
0
 public static ConstructorCall HeapConstructor(TypeMutability mutability, NameReference innerTypeName, params IExpression[] arguments)
 {
     return(HeapConstructor(mutability, innerTypeName, arguments.Select(it => FunctionArgument.Create(it)).ToArray()));
 }
Esempio n. 19
0
 public static NameReference ItNameReference(TypeMutability mutability = TypeMutability.None)
 {
     return(NameReference.Create(mutability, ItTypeName));
 }
Esempio n. 20
0
 public static NameReference Create(TypeMutability overrideMutability, IExpression prefix, string name)
 {
     return(new NameReference(overrideMutability, prefix, BrowseMode.None, null,
                              name, Enumerable.Empty <TemplateArgument>(),
                              ExpressionReadMode.ReadRequired, isRoot: false));
 }