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 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); }
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}"); } }
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); } } }