public EntityInstance GetInstance(TypeMutability overrideMutability, TemplateTranslation translation, Lifetime lifetime) { return(this.instancesCache.GetInstance(overrideMutability, translation, lifetime)); }
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)); }
public static IEntityInstance Rebuild(this IEntityInstance instance, ComputationContext ctx, TypeMutability mutability, bool deep = true) { return(instance.Map(elem => elem.Rebuild(ctx, mutability, deep))); }
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); } } }
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); }
public static NameReference SelfNameReference(TypeMutability mutability = TypeMutability.None) { return(NameReference.Create(mutability, SelfTypeTypeName)); }
public static NameReference Create(TypeMutability overrideMutability, string name, params INameReference[] arguments) { return(Create(overrideMutability, null, name, arguments)); }
internal static Alloc Create(NameReference innerTypename, Memory memory, TypeMutability mutability = TypeMutability.None) { return(new Alloc(innerTypename, memory, mutability)); }
public static IExpression HeapConstructor(NameReference innerTypeName, TypeMutability mutability, params FunctionArgument[] arguments) { return(ConstructorCall.HeapConstructor(mutability, innerTypeName, arguments).Build()); }
internal EntityInstance Build(IEnumerable <IEntityInstance> templateArguments, TypeMutability overrideMutability) { TemplateTranslation combined = this.Translation.Overridden(templateArguments); return(this.Target.GetInstance(overrideMutability, combined, this.Lifetime)); }
internal EntityInstance Build(IEnumerable <TemplateArgument> templateArguments, TypeMutability overrideMutability) { return(Build(templateArguments.Select(it => it.TypeName.Evaluation.Components), overrideMutability)); }
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); }
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 NameReference CreateTypeNameReference(TypeMutability mutability = TypeMutability.None) { return(this.name.CreateNameReference(prefix: null, mutability: mutability)); }
internal EntityInstance GetInstance(IEntity entity, TypeMutability overrideMutability, TemplateTranslation translation, Lifetime lifetime) { if (!this.cache.TryGetValue(lifetime, out EntityInstance[] inner_cache))
public static ConstructorCall HeapConstructor(string innerTypeName, TypeMutability mutability, params IExpression[] arguments) { return(HeapConstructor(mutability, NameReference.Create(innerTypeName), arguments)); }
public static NameReference SizeNameReference(TypeMutability mutability = TypeMutability.None) { return(NameReference.Create(mutability, NameReference.Root, SizeTypeName)); }
public static ConstructorCall HeapConstructor(TypeMutability mutability, NameReference innerTypeName, params IExpression[] arguments) { return(HeapConstructor(mutability, innerTypeName, arguments.Select(it => FunctionArgument.Create(it)).ToArray())); }
public static NameReference ItNameReference(TypeMutability mutability = TypeMutability.None) { return(NameReference.Create(mutability, ItTypeName)); }
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)); }