private static TypeSymbol NarrowTypeInternal(ITypeManager typeManager, SyntaxBase expression, TypeSymbol targetType, IDiagnosticWriter diagnosticWriter, TypeMismatchErrorFactory typeMismatchErrorFactory, bool skipConstantCheck, bool skipTypeErrors) { if (targetType is ResourceType targetResourceType) { // When assigning a resource, we're really assigning the value of the resource body. var narrowedBody = NarrowTypeInternal(typeManager, expression, targetResourceType.Body.Type, diagnosticWriter, typeMismatchErrorFactory, skipConstantCheck, skipTypeErrors); return(new ResourceType(targetResourceType.TypeReference, targetResourceType.ValidParentScopes, narrowedBody)); } if (targetType is ModuleType targetModuleType) { var narrowedBody = NarrowTypeInternal(typeManager, expression, targetModuleType.Body.Type, diagnosticWriter, typeMismatchErrorFactory, skipConstantCheck, skipTypeErrors); return(new ModuleType(targetModuleType.Name, targetModuleType.ValidParentScopes, narrowedBody)); } // TODO: The type of this expression and all subexpressions should be cached var expressionType = typeManager.GetTypeInfo(expression); // since we dynamically checked type, we need to collect the errors but only if the caller wants them if (skipTypeErrors == false && expressionType is ErrorType) { diagnosticWriter.WriteMultiple(expressionType.GetDiagnostics()); return(targetType); } // basic assignability check if (AreTypesAssignable(expressionType, targetType) == false) { // fundamentally different types - cannot assign diagnosticWriter.Write(typeMismatchErrorFactory(targetType, expressionType, expression)); return(targetType); } // object assignability check if (expression is ObjectSyntax objectValue) { switch (targetType) { case ObjectType targetObjectType: return(NarrowObjectType(typeManager, objectValue, targetObjectType, diagnosticWriter, skipConstantCheck)); case DiscriminatedObjectType targetDiscriminated: return(NarrowDiscriminatedObjectType(typeManager, objectValue, targetDiscriminated, diagnosticWriter, skipConstantCheck)); } } // if-condition assignability check if (expression is IfConditionSyntax { Body : ObjectSyntax body })
protected void CollectDiagnostics(Symbol symbol) { diagnosticWriter.WriteMultiple(symbol.GetDiagnostics()); }