private void ResolveBodyTypesInField(FieldDeclarationSyntax fieldDeclaration) { if (fieldDeclaration.Initializer == null) return; var resolver = new ExpressionTypeResolver(fieldDeclaration.File, diagnostics); resolver.CheckExpressionType(fieldDeclaration.Initializer, fieldDeclaration.Type.Fulfilled()); }
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(); }
private void ResolveSignatureTypesInField(FieldDeclarationSyntax field) { var resolver = new ExpressionTypeResolver(field.File, diagnostics); field.Type.BeginFulfilling(); var type = resolver.CheckAndEvaluateTypeExpression(field.TypeExpression); field.Type.Fulfill(type); }
private FixedList<DataType> ResolveTypesInParameters( FunctionDeclarationSyntax function, ExpressionTypeResolver expressionResolver) { var types = new List<DataType>(); foreach (var parameter in function.Parameters) switch (parameter) { case NamedParameterSyntax namedParameter: { parameter.Type.BeginFulfilling(); var type = expressionResolver.CheckAndEvaluateTypeExpression(namedParameter .TypeExpression); types.Add(parameter.Type.Fulfill(type)); } break; case SelfParameterSyntax _: // Skip, we have already handled the self parameter break; case FieldParameterSyntax fieldParameter: throw new NotImplementedException(); default: throw NonExhaustiveMatchException.For(parameter); } return types.ToFixedList(); }
private static DataType ResolveReturnType( FunctionDeclarationSyntax function, ExpressionSyntax returnTypeExpression, ExpressionTypeResolver expressionResolver) { var returnType = returnTypeExpression != null ? expressionResolver.CheckAndEvaluateTypeExpression(returnTypeExpression) : DataType.Void; return function.ReturnType.Fulfill(returnType); }
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(); }
private static void ResolveTypesInGenericParameters( FixedList<GenericParameterSyntax> genericParameters, ExpressionTypeResolver expressionResolver) { foreach (var parameter in genericParameters) { parameter.Type.BeginFulfilling(); var type = parameter.TypeExpression == null ? DataType.Type : expressionResolver.CheckAndEvaluateTypeExpression(parameter.TypeExpression); parameter.Type.Fulfill(type); } }
private static DataType ResolveReturnType( FunctionDeclarationSyntax function, ExpressionTypeResolver expressionResolver) { function.ReturnType.BeginFulfilling(); switch (function) { case NamedFunctionDeclarationSyntax namedFunction: return ResolveReturnType(function, namedFunction.ReturnTypeExpression, expressionResolver); case OperatorDeclarationSyntax @operator: return ResolveReturnType(function, @operator.ReturnTypeExpression, expressionResolver); case ConstructorDeclarationSyntax _: case InitializerDeclarationSyntax _: return function.ReturnType.Fulfill(function.DeclaringType.Metatype.Instance); default: throw NonExhaustiveMatchException.For(function); } }
/// <summary> /// If the type has not been resolved, this resolves it. This function /// also watches for type cycles and reports an error. /// </summary> private void ResolveSignatureTypesInTypeDeclaration(TypeDeclarationSyntax declaration) { switch (declaration.Type.State) { case PromiseState.InProgress: diagnostics.Add(TypeError.CircularDefinition(declaration.File, declaration.NameSpan, declaration.Name)); return; case PromiseState.Fulfilled: return; // We have already resolved it case PromiseState.Pending: // we need to compute it break; } declaration.Type.BeginFulfilling(); var expressionChecker = new ExpressionTypeResolver(declaration.File, diagnostics); FixedList<DataType> genericParameterTypes = null; if (declaration.GenericParameters != null) { var genericParameters = declaration.GenericParameters; ResolveTypesInGenericParameters(genericParameters, expressionChecker); genericParameterTypes = genericParameters.Select(p => p.Type.Fulfilled()).ToFixedList(); } switch (declaration) { case ClassDeclarationSyntax classDeclaration: var classType = new ObjectType(declaration, classDeclaration.Modifiers.Any(m => m is IMutableKeywordToken), genericParameterTypes, Lifetime.None); declaration.Type.Fulfill(new Metatype(classType)); classDeclaration.CreateDefaultConstructor(); break; case StructDeclarationSyntax structDeclaration: var structType = new ObjectType(declaration, structDeclaration.Modifiers.Any(m => m is IMutableKeywordToken), genericParameterTypes, Lifetime.None); declaration.Type.Fulfill(new Metatype(structType)); break; case EnumStructDeclarationSyntax enumStructDeclaration: var enumStructType = new ObjectType(declaration, enumStructDeclaration.Modifiers.Any(m => m is IMutableKeywordToken), genericParameterTypes, Lifetime.None); declaration.Type.Fulfill(new Metatype(enumStructType)); break; case EnumClassDeclarationSyntax enumStructDeclaration: var enumClassType = new ObjectType(declaration, enumStructDeclaration.Modifiers.Any(m => m is IMutableKeywordToken), genericParameterTypes, Lifetime.None); declaration.Type.Fulfill(new Metatype(enumClassType)); break; case TraitDeclarationSyntax declarationSyntax: var type = new ObjectType(declaration, declarationSyntax.Modifiers.Any(m => m is IMutableKeywordToken), genericParameterTypes, Lifetime.None); declaration.Type.Fulfill(new Metatype(type)); break; default: throw NonExhaustiveMatchException.For(declaration); } }