private void ResolveSignatureTypesInFunction(FunctionDeclarationSyntax function)
        {
            function.Type.BeginFulfilling();
            var diagnosticCount = diagnostics.Count;

            // Resolve the declaring type because we need its type for things like `self`
            if (function.DeclaringType != null)
                ResolveSignatureTypesInTypeDeclaration(function.DeclaringType);

            var selfType = ResolveSelfType(function);
            var resolver = new ExpressionTypeResolver(function.File, diagnostics, selfType);

            if (function.GenericParameters != null)
                ResolveTypesInGenericParameters(function.GenericParameters, resolver);

            var parameterTypes = ResolveTypesInParameters(function, resolver);

            var returnType = ResolveReturnType(function, resolver);
            DataType functionType = new FunctionType(parameterTypes, returnType);

            if (function.GenericParameters?.Any() ?? false)
                functionType = new MetaFunctionType(function.GenericParameters.Select(p => p.Type.Fulfilled()), functionType);

            function.Type.Fulfill(functionType);
            if (diagnosticCount != diagnostics.Count) function.Poison();
        }
Esempio n. 2
0
 public override void VisitVariableDeclarationStatement(VariableDeclarationStatementSyntax variableDeclaration, BindingScope bindingScope)
 {
     base.VisitVariableDeclarationStatement(variableDeclaration, bindingScope);
     if (bindingScope.Lookup(variableDeclaration.Name, out var binding))
     {
         if (binding.MutableBinding)
         {
             diagnostics.Add(SemanticError.CantRebindMutableBinding(function.File, variableDeclaration.NameSpan));
             function.Poison();
         }
         else if (variableDeclaration.MutableBinding)
         {
             diagnostics.Add(SemanticError.CantRebindAsMutableBinding(function.File, variableDeclaration.NameSpan));
             function.Poison();
         }
     }
 }
 public override void VisitIdentifierName(IdentifierNameSyntax identifierName, bool lvalue)
 {
     if (!lvalue || identifierName.ReferencedSymbol.MutableBinding)
     {
         return;
     }
     diagnostics.Add(SemanticError.CantAssignToImmutable(function.File, identifierName.Span));
     function.Poison();
 }
 private void CheckAssignment(DataType assignToType, ExpressionSyntax value)
 {
     if (assignToType is ReferenceType referenceType &&
         referenceType.IsOwned)
     {
         if (value.ValueSemantics != ValueSemantics.Move)
         {
             diagnostics.Add(SemanticError.CantMove(function.File, value));
             function.Poison();
         }
     }
 }
        private void ResolveBodyTypesInFunction(FunctionDeclarationSyntax function)
        {
            if (function.Body == null) return;

            var diagnosticCount = diagnostics.Count;
            // TODO the return types of constructors and init functions should probably be void for purposes of expressions
            var resolver = new ExpressionTypeResolver(function.File, diagnostics, (Metatype)function.DeclaringType?.Type.Fulfilled(), function.ReturnType.Fulfilled());
            // The body of a function shouldn't itself evaluate to anything.
            // There should be no `=> value` for the block, so the type is `void`.
            resolver.CheckExpressionType(function.Body, DataType.Void);
            if (diagnosticCount != diagnostics.Count) function.Poison();
        }