public static FunctionDefinition CreateAutoSetter(string autoFieldName, INameReference typeName, EntityModifier modifier = null) { return(FunctionDefinition.CreateFunction(EntityModifier.Mutable | EntityModifier.Accessor | modifier, NameDefinition.Create(NameFactory.PropertySetter), null, new[] { FunctionParameter.Create(NameFactory.PropertySetterValueParameter, typeName) }, ExpressionReadMode.OptionalUse, NameFactory.UnitNameReference(), Block.CreateStatement(new[] { Assignment.CreateStatement( NameReference.CreateThised(autoFieldName), NameReference.Create(NameFactory.PropertySetterValueParameter)) }))); }
public static FunctionDefinition CreateIndexerSetter(INameReference propertyTypeName, IEnumerable <FunctionParameter> parameters, EntityModifier modifier, Block body) { modifier |= EntityModifier.Mutable | EntityModifier.Accessor; return(FunctionBuilder.Create(NameFactory.PropertySetter, ExpressionReadMode.OptionalUse, NameFactory.UnitNameReference(), body) .SetModifier(modifier) .Parameters(parameters.Concat(FunctionParameter.Create(NameFactory.PropertySetterValueParameter, // we add "value" parameter at the end so the name has to be required, // because we don't know what comes first propertyTypeName, Variadic.None, null, isNameRequired: true, usageMode: modifier.HasNative ? ExpressionReadMode.CannotBeRead : ExpressionReadMode.ReadRequired)))); }
internal bool NOT_USED_CounterpartParameter(IOwnedNode thisScope, FunctionParameter other, IOwnedNode otherScope) { // todo: add relative checking so foo<T>(t T) will be equal to bar<X>(x X) if (!this.Variadic.Equals(other.Variadic)) { return(false); } if (!EntityBareNameComparer.Instance.Equals(this.Name, other.Name)) { return(false); } if (this.TypeName.Evaluation.Components.IsExactlySame(other.TypeName.Evaluation.Components, jokerMatchesAll: true)) { return(false); } return(true); }
public override bool AttachTo(IOwnedNode parent) { // IMPORTANT: when function is attached to a type, the type is NOT fully constructed! bool result = base.AttachTo(parent); // property accessors will see owner type in second attach, when property is attached to type TypeDefinition owner_type = this.ContainingType(); if (this.MetaThisParameter == null && owner_type != null && // method !this.Modifier.HasStatic && !owner_type.Modifier.HasStatic) { NameReference type_name = owner_type.InstanceOf.NameOf; // initially already tied to target this.MetaThisParameter = FunctionParameter.Create(NameFactory.ThisVariableName, owner_type.Modifier.HasHeapOnly ? NameFactory.PointerNameReference(type_name) : NameFactory.ReferenceNameReference(type_name), Variadic.None, null, isNameRequired: false, usageMode: ExpressionReadMode.OptionalUse); this.MetaThisParameter.AttachTo(this); } // marking regular functions a static one will make further processing easier if (!this.Modifier.HasStatic && parent is IEntity entity_parent && entity_parent.Modifier.HasStatic) { this.SetModifier(this.Modifier | EntityModifier.Static); } if (!this.Modifier.IsAccessSet) { if (parent is TypeContainerDefinition) { this.SetModifier(this.Modifier | EntityModifier.Public); } else if (parent is Property prop) { this.SetModifier(this.Modifier | prop.Modifier.AccessLevels); } } return(result); }
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); } } }
public override void Validate(ComputationContext ctx) { this.ValidateRestrictedMember(ctx); TypeDefinition type_owner = this.ContainingType(); if (type_owner != null && type_owner.IsTrait && this.IsAnyConstructor()) { ctx.AddError(ErrorCode.TraitConstructor, this); } if (this.Name.Name == NameFactory.ConvertFunctionName && type_owner != null) { if (this.Parameters.Any()) { ctx.AddError(ErrorCode.ConverterWithParameters, this); } if (!this.Modifier.HasPinned && !type_owner.Modifier.HasEnum && !type_owner.Modifier.IsSealed) { ctx.AddError(ErrorCode.ConverterNotPinned, this); } if (this.CallMode != ExpressionReadMode.ReadRequired) { ctx.AddError(ErrorCode.ConverterDeclaredWithIgnoredOutput, this); } } if (!this.IsAnyConstructor()) { foreach (INameReference typename in this.Parameters.Select(it => it.TypeName)) { typename.ValidateTypeNameVariance(ctx, VarianceMode.In); } this.ResultTypeName.ValidateTypeNameVariance(ctx, VarianceMode.Out); } if (!ctx.Env.Options.AllowInvalidMainResult && this == ctx.Env.MainFunction(ctx) && !ctx.Env.Nat8Type.InstanceOf.IsIdentical(this.ResultTypeName.Evaluation.Components)) { ctx.AddError(ErrorCode.MainFunctionInvalidResultType, this.ResultTypeName); } if (this.Modifier.HasOverride && !this.Modifier.HasUnchainBase) { if (!this.IsDeclaration && this.ContainingType().DerivationTable.TryGetSuper(this, out FunctionDefinition dummy) && !this.DescendantNodes().WhereType <FunctionCall>().Any(it => it.Name.IsSuperReference)) { ctx.AddError(ErrorCode.DerivationWithoutSuperCall, this); } } if (!this.IsDeclaration && !this.Modifier.HasNative) { if (!ctx.Env.IsOfUnitType(this.ResultTypeName) && !this.UserBody.Validation.IsTerminated) { ctx.AddError(ErrorCode.MissingReturn, this.UserBody); } } FunctionParameter tail_anon_variadic = this.Parameters .Where(it => it.IsVariadic) .Skip(1) // first variadic can be anonymous .FirstOrDefault(it => !it.IsNameRequired); if (tail_anon_variadic != null) { ctx.AddError(ErrorCode.AnonymousTailVariadicParameter, tail_anon_variadic); } // extensions { foreach (FunctionParameter param in this.Parameters.Skip(1).Where(it => it.Modifier.HasThis)) { ctx.AddError(ErrorCode.NonPrimaryThisParameter, param); } if (this.IsExtension) { FunctionParameter param = this.Parameters.First(); if (param.IsVariadic) { ctx.AddError(ErrorCode.VariadicThisParameter, param); } else if (param.IsOptional) { ctx.AddError(ErrorCode.OptionalThisParameter, param); } if (!ctx.Env.IsReferenceOfType(param.Evaluation.Components)) { ctx.AddError(ErrorCode.NonReferenceThisParameter, param); } } } }
private void setResultParameter(INameReference result) { this.ResultParameter = FunctionParameter.Create("", result, ExpressionReadMode.OptionalUse); }