Ejemplo n.º 1
0
        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
            })
Ejemplo n.º 2
0
 protected void CollectDiagnostics(Symbol symbol)
 {
     diagnosticWriter.WriteMultiple(symbol.GetDiagnostics());
 }