Esempio n. 1
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. 2
0
        public static FunctionDefinition TryGetSuperFunction(this FunctionDefinition func, ComputationContext ctx)
        {
            TypeDefinition curr_type = func.ContainingType();

            if (curr_type == null)
            {
                return(null); // we need to be within type to get base function
            }
            if (!curr_type.IsSurfed)
            {
                throw new NotImplementedException("We need at this point the type surface is processed, yet we are processing the body (?) of the function");
            }

            if (!curr_type.DerivationTable.TryGetSuper(func, out FunctionDefinition super))
            {
                return(null);
            }

            return(super);
        }
Esempio n. 3
0
        private async Task <ExecValue> executeNativeFunctionAsync(ExecutionContext ctx, FunctionDefinition func)
        {
            TypeDefinition owner_type = func.ContainingType();

            // meta-this is always passed as reference or pointer, so we can blindly dereference it
            ObjectData this_value = func.Modifier.HasStatic ? null : ctx.ThisArgument.DereferencedOnce();

            if (owner_type.Modifier.HasEnum)
            {
                return(await executeNativeEnumFunctionAsync(ctx, func, this_value).ConfigureAwait(false));
            }
            else if (owner_type == ctx.Env.UnitType)
            {
                return(await executeNativeUnitFunctionAsync(ctx, func, this_value).ConfigureAwait(false));
            }
            else if (owner_type == ctx.Env.Utf8StringType)
            {
                return(await executeNativeUtf8StringFunctionAsync(ctx, func, this_value).ConfigureAwait(false));
            }
            else if (owner_type == ctx.Env.RegexType)
            {
                return(await executeNativeRegexFunctionAsync(ctx, func, this_value).ConfigureAwait(false));
            }
            else if (owner_type == ctx.Env.FileType)
            {
                return(await executeNativeFileFunctionAsync(ctx, func).ConfigureAwait(false));
            }
            else if (owner_type == ctx.Env.ChunkType)
            {
                return(await executeNativeChunkFunctionAsync(ctx, func, this_value).ConfigureAwait(false));
            }
            else if (owner_type == ctx.Env.Int16Type)
            {
                return(await executeNativeInt16FunctionAsync(ctx, func, this_value).ConfigureAwait(false));
            }
            else if (owner_type == ctx.Env.Int64Type)
            {
                return(await executeNativeInt64FunctionAsync(ctx, func, this_value).ConfigureAwait(false));
            }
            else if (owner_type == ctx.Env.Nat8Type)
            {
                return(await executeNativeNat8FunctionAsync(ctx, func, this_value).ConfigureAwait(false));
            }
            else if (owner_type == ctx.Env.Nat64Type)
            {
                return(await executeNativeNat64FunctionAsync(ctx, func, this_value).ConfigureAwait(false));
            }
            else if (owner_type == ctx.Env.Real64Type)
            {
                return(await executeNativeReal64FunctionAsync(ctx, func, this_value).ConfigureAwait(false));
            }
            else if (owner_type == ctx.Env.IObjectType)
            {
                return(await executeNativeIObjectFunctionAsync(ctx, func, this_value).ConfigureAwait(false));
            }
            else if (owner_type == ctx.Env.BoolType)
            {
                return(await executeNativeBoolFunctionAsync(ctx, func, this_value).ConfigureAwait(false));
            }
            else if (owner_type == ctx.Env.CharType)
            {
                return(await executeNativeCharFunctionAsync(ctx, func, this_value).ConfigureAwait(false));
            }
            else if (owner_type == ctx.Env.DateType)
            {
                return(await executeNativeDateFunctionAsync(ctx, func, this_value).ConfigureAwait(false));
            }
            else if (owner_type == ctx.Env.ChannelType)
            {
                return(await executeNativeChannelFunctionAsync(ctx, func, this_value).ConfigureAwait(false));
            }
            else
            {
                throw new NotImplementedException($"{owner_type}");
            }
        }
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);
                }
            }
        }