Пример #1
0
 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))
     })));
 }
Пример #2
0
        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))));
        }
Пример #3
0
        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);
        }
Пример #4
0
        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);
        }
Пример #5
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);
                }
            }
        }
Пример #6
0
        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);
                    }
                }
            }
        }
Пример #7
0
 private void setResultParameter(INameReference result)
 {
     this.ResultParameter = FunctionParameter.Create("", result, ExpressionReadMode.OptionalUse);
 }