Esempio n. 1
0
 public BDDTestSuite(IReflectionProvider reflectionProvider, ITypeManager typeManager, Type fixtureType)
     : base(fixtureType)
 {
     _reflectionProvider = reflectionProvider;
     _typeManager = typeManager;
     BuildTestsFromFixtureType(fixtureType);
 }
Esempio n. 2
0
 public QueryFactory(
     ITypeManager typeManager,
     IIdAccessor idAccessor)
 {
     _typeManager = typeManager;
     _idAccessor  = idAccessor;
 }
Esempio n. 3
0
        public TypeSymbol GetAssignedType(ITypeManager typeManager, ArraySyntax?allowedSyntax)
        {
            var assignedType = this.GetDeclaredType();

            // TODO: remove SyntaxHelper.TryGetAllowedSyntax when we drop parameter modifiers support.
            if (allowedSyntax is not null && !allowedSyntax.Items.Any())
            {
                return(ErrorType.Create(DiagnosticBuilder.ForPosition(allowedSyntax).AllowedMustContainItems()));
            }

            var allowedItemTypes = allowedSyntax?.Items.Select(typeManager.GetTypeInfo);

            if (ReferenceEquals(assignedType, LanguageConstants.String))
            {
                if (allowedItemTypes?.All(itemType => itemType is StringLiteralType) == true)
                {
                    assignedType = UnionType.Create(allowedItemTypes);
                }
                else
                {
                    // In order to support assignment for a generic string to enum-typed properties (which generally is forbidden),
                    // we need to relax the validation for string parameters without 'allowed' values specified.
                    assignedType = LanguageConstants.LooseString;
                }
            }

            if (ReferenceEquals(assignedType, LanguageConstants.Array) &&
                allowedItemTypes?.All(itemType => itemType is StringLiteralType) == true)
            {
                assignedType = new TypedArrayType(UnionType.Create(allowedItemTypes), TypeSymbolValidationFlags.Default);
            }

            return(assignedType);
        }
Esempio n. 4
0
 public SemanticModel(FileSymbol root, ITypeManager typeManager, IDictionary <SyntaxBase, Symbol> bindings, ResourceScopeType targetScope)
 {
     this.Root        = root;
     this.typeManager = typeManager;
     this.TargetScope = targetScope;
     this.bindings    = bindings.ToImmutableDictionary();
 }
Esempio n. 5
0
        public static TypeSymbol NarrowTypeAndCollectDiagnostics(ITypeManager typeManager, SyntaxBase expression, TypeSymbol targetType, IDiagnosticWriter diagnosticWriter)
        {
            // generic error creator if a better one was not specified.
            TypeMismatchErrorFactory typeMismatchErrorFactory = (expectedType, actualType, errorExpression) => DiagnosticBuilder.ForPosition(errorExpression).ExpectedValueTypeMismatch(ShouldWarn(targetType), expectedType, actualType);

            return(NarrowTypeInternal(typeManager, expression, targetType, diagnosticWriter, typeMismatchErrorFactory, skipConstantCheck: false, skipTypeErrors: false));
        }
        public TypeSymbol GetAssignedType(ITypeManager typeManager)
        {
            var assignedType = this.GetDeclaredType();

            var allowedSyntax = SyntaxHelper.TryGetAllowedSyntax(this);

            if (allowedSyntax != null && !allowedSyntax.Items.Any())
            {
                return(ErrorType.Create(DiagnosticBuilder.ForPosition(allowedSyntax).AllowedMustContainItems()));
            }

            if (object.ReferenceEquals(assignedType, LanguageConstants.String))
            {
                var allowedItemTypes = allowedSyntax?.Items.Select(typeManager.GetTypeInfo);

                if (allowedItemTypes != null && allowedItemTypes.All(itemType => itemType is StringLiteralType))
                {
                    assignedType = UnionType.Create(allowedItemTypes);
                }
                else
                {
                    // In order to support assignment for a generic string to enum-typed properties (which generally is forbidden),
                    // we need to relax the validation for string parameters without 'allowed' values specified.
                    assignedType = LanguageConstants.LooseString;
                }
            }

            return(assignedType);
        }
Esempio n. 7
0
        private static TypeSymbol NarrowArrayAssignmentType(ITypeManager typeManager, ArraySyntax expression, ArrayType targetType, IDiagnosticWriter diagnosticWriter, bool skipConstantCheck)
        {
            // if we have parse errors, no need to check assignability
            // we should not return the parse errors however because they will get double collected
            if (expression.HasParseErrors())
            {
                return(targetType);
            }

            var arrayProperties = new List <TypeSymbol>();

            foreach (var arrayItemSyntax in expression.Items)
            {
                arrayProperties.Add(NarrowTypeInternal(
                                        typeManager,
                                        arrayItemSyntax.Value,
                                        targetType.Item.Type,
                                        diagnosticWriter,
                                        (expectedType, actualType, errorExpression) => DiagnosticBuilder.ForPosition(errorExpression).ArrayTypeMismatch(ShouldWarn(targetType), expectedType, actualType),
                                        skipConstantCheck,
                                        skipTypeErrors: true));
            }

            return(new TypedArrayType(UnionType.Create(arrayProperties), targetType.ValidationFlags));
        }
Esempio n. 8
0
 public SemanticModel(FileSymbol root, ITypeManager typeManager, IDictionary <SyntaxBase, Symbol> bindings, ResourceScopeType targetScope)
 {
     this.Root                   = root;
     this.typeManager            = typeManager;
     this.TargetScope            = targetScope;
     this.bindings               = bindings.ToImmutableDictionary();
     this.emitLimitationInfoLazy = new Lazy <EmitLimitationInfo>(() => EmitLimitationCalculator.Calculate(this));
 }
Esempio n. 9
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
            })
Esempio n. 10
0
 public DeclaredTypeManager(SyntaxHierarchy hierarchy, ITypeManager typeManager, IResourceTypeProvider resourceTypeProvider, IReadOnlyDictionary <SyntaxBase, Symbol> bindings, IReadOnlyDictionary <DeclaredSymbol, ImmutableArray <DeclaredSymbol> > cyclesBySyntax, ResourceScopeType targetScope)
 {
     this.hierarchy            = hierarchy;
     this.typeManager          = typeManager;
     this.resourceTypeProvider = resourceTypeProvider;
     this.bindings             = bindings;
     this.cyclesBySyntax       = cyclesBySyntax;
     this.targetScope          = targetScope;
 }
Esempio n. 11
0
        public void Validate(DecoratorSyntax decoratorSyntax, TypeSymbol targetType, ITypeManager typeManager, IDiagnosticWriter diagnosticWriter)
        {
            if (targetType is ErrorType)
            {
                return;
            }

            this.validator?.Invoke(this.Overload.Name, decoratorSyntax, targetType, typeManager, diagnosticWriter);
        }
Esempio n. 12
0
        private static TypeSymbol NarrowTypeInternal(ITypeManager typeManager,
                                                     SyntaxBase expression,
                                                     TypeSymbol targetType,
                                                     IList <Diagnostic> diagnostics,
                                                     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, diagnostics, typeMismatchErrorFactory, skipConstantCheck, skipTypeErrors);

                return(new ResourceType(targetResourceType.TypeReference, narrowedBody, targetResourceType.ValidationFlags));
            }

            // TODO: The type of this expression and all subexpressions should be cached
            TypeSymbol?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 ErrorTypeSymbol)
            {
                diagnostics.AddRange(expressionType.GetDiagnostics());
            }

            // basic assignability check
            if (AreTypesAssignable(expressionType, targetType) == false)
            {
                // fundamentally different types - cannot assign
                diagnostics.Add(typeMismatchErrorFactory(targetType, expressionType, expression));
                return(targetType);
            }

            // object assignability check
            if (expression is ObjectSyntax objectValue && targetType is ObjectType targetObjectType)
            {
                return(NarrowObjectType(typeManager, objectValue, targetObjectType, diagnostics, skipConstantCheck));
            }

            if (expression is ObjectSyntax objectDiscriminated && targetType is DiscriminatedObjectType targetDiscriminated)
            {
                return(NarrowDiscriminatedObjectType(typeManager, objectDiscriminated, targetDiscriminated, diagnostics, skipConstantCheck));
            }

            // array assignability check
            if (expression is ArraySyntax arrayValue && targetType is ArrayType targetArrayType)
            {
                return(NarrowArrayAssignmentType(typeManager, arrayValue, targetArrayType, diagnostics, skipConstantCheck));
            }

            if (targetType is UnionType targetUnionType)
            {
                return(UnionType.Create(targetUnionType.Members.Where(x => AreTypesAssignable(expressionType, x.Type) == true)));
            }

            return(targetType);
        }
Esempio n. 13
0
 public QueryProvider(ITypeManager typeManager, IIdAccessor idAccessor, ISession session, IEnumerable <string> index = null)
 {
     _sessionContext = new SessionContext()
     {
         TypeManager = typeManager,
         IdAccessor  = idAccessor
     };
     _session = session;
     _index   = index;
 }
Esempio n. 14
0
        public static IEnumerable <Diagnostic> GetExpressionAssignmentDiagnostics(ITypeManager typeManager, SyntaxBase expression, TypeSymbol targetType, Func <TypeSymbol, TypeSymbol, SyntaxBase, Diagnostic>?typeMismatchErrorFactory = null)
        {
            // generic error creator if a better one was not specified.
            typeMismatchErrorFactory ??= (expectedType, actualType, errorExpression) => DiagnosticBuilder.ForPosition(errorExpression).ExpectedValueTypeMismatch(expectedType.Name, actualType.Name);

            var diagnostics = new List <Diagnostic>();

            GetExpressionAssignmentDiagnosticsInternal(typeManager, expression, targetType, diagnostics, typeMismatchErrorFactory, skipConstantCheck: false, skipTypeErrors: false);

            return(diagnostics);
        }
Esempio n. 15
0
        public void Validate(DecoratorSyntax decoratorSyntax, TypeSymbol targetType, ITypeManager typeManager, IBinder binder, IDiagnosticWriter diagnosticWriter)
        {
            if (targetType is ErrorType)
            {
                return;
            }

            if (!this.CanAttachTo(targetType))
            {
                diagnosticWriter.Write(DiagnosticBuilder.ForPosition(decoratorSyntax).CannotAttachDecoratorToTarget(this.Overload.Name, attachableType, targetType));
            }

            // Invoke custom validator if provided.
            this.validator?.Invoke(this.Overload.Name, decoratorSyntax, targetType, typeManager, binder, diagnosticWriter);
        }
Esempio n. 16
0
        private static void GetDiscriminatedObjectAssignmentDiagnostics(ITypeManager typeManager, ObjectSyntax expression, DiscriminatedObjectType targetType, IList <Diagnostic> diagnostics, bool skipConstantCheck)
        {
            // if we have parse errors, there's no point to check assignability
            // we should not return the parse errors however because they will get double collected
            if (expression.HasParseErrors())
            {
                return;
            }

            var propertyMap = expression.ToPropertyDictionary();

            if (!propertyMap.TryGetValue(targetType.DiscriminatorKey, out var discriminatorProperty))
            {
                // object doesn't contain the discriminator field
                diagnostics.Add(DiagnosticBuilder.ForPosition(expression).MissingRequiredProperty(targetType.DiscriminatorKey, targetType.DiscriminatorKeysUnionType));
                return;
            }

            // At some point in the future we may want to relax the expectation of a string literal key, and allow a generic string.
            // In this case, the best we can do is validate against the union of all the settable properties.
            // Let's not do this just yet, and see if a use-case arises.

            var discriminatorType = typeManager.GetTypeInfo(discriminatorProperty.Value);

            if (!(discriminatorType is StringLiteralType stringLiteralDiscriminator))
            {
                diagnostics.Add(DiagnosticBuilder.ForPosition(expression).PropertyTypeMismatch(targetType.DiscriminatorKey, targetType.DiscriminatorKeysUnionType, discriminatorType));
                return;
            }

            if (!targetType.UnionMembersByKey.TryGetValue(stringLiteralDiscriminator.Name, out var selectedObjectReference))
            {
                // no matches
                diagnostics.Add(DiagnosticBuilder.ForPosition(discriminatorProperty.Value).PropertyTypeMismatch(targetType.DiscriminatorKey, targetType.DiscriminatorKeysUnionType, discriminatorType));
                return;
            }

            if (!(selectedObjectReference.Type is ObjectType selectedObjectType))
            {
                throw new InvalidOperationException($"Discriminated type {targetType.Name} contains non-object member");
            }

            // we have a match!
            GetObjectAssignmentDiagnostics(typeManager, expression, selectedObjectType, diagnostics, skipConstantCheck);
        }
Esempio n. 17
0
        private static void GetExpressionAssignmentDiagnosticsInternal(ITypeManager typeManager,
                                                                       SyntaxBase expression,
                                                                       TypeSymbol targetType,
                                                                       IList <Diagnostic> diagnostics,
                                                                       Func <TypeSymbol, TypeSymbol, SyntaxBase, Diagnostic> typeMismatchErrorFactory,
                                                                       bool skipConstantCheck,
                                                                       bool skipTypeErrors)
        {
            // TODO: The type of this expression and all subexpressions should be cached
            TypeSymbol?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 ErrorTypeSymbol)
            {
                diagnostics.AddRange(expressionType.GetDiagnostics());
            }

            // basic assignability check
            if (AreTypesAssignable(expressionType, targetType) == false)
            {
                // fundamentally different types - cannot assign
                diagnostics.Add(typeMismatchErrorFactory(targetType, expressionType, expression));
                return;
            }

            // object assignability check
            if (expression is ObjectSyntax objectValue && targetType is ObjectType targetObjectType)
            {
                GetObjectAssignmentDiagnostics(typeManager, objectValue, targetObjectType, diagnostics, skipConstantCheck);
                return;
            }

            if (expression is ObjectSyntax objectDiscriminated && targetType is DiscriminatedObjectType targetDiscriminated)
            {
                GetDiscriminatedObjectAssignmentDiagnostics(typeManager, objectDiscriminated, targetDiscriminated, diagnostics, skipConstantCheck);
                return;
            }

            // array assignability check
            if (expression is ArraySyntax arrayValue && targetType is ArrayType targetArrayType)
            {
                GetArrayAssignmentDiagnostics(typeManager, arrayValue, targetArrayType, diagnostics, skipConstantCheck);
                return;
            }
        }
Esempio n. 18
0
        private static IEnumerable <ErrorDiagnostic> GetArrayAssignmentDiagnostics(ITypeManager typeManager, ArraySyntax expression, ArrayType targetType, bool skipConstantCheck)
        {
            // if we have parse errors, no need to check assignability
            // we should not return the parse errors however because they will get double collected
            if (expression.HasParseErrors())
            {
                return(Enumerable.Empty <ErrorDiagnostic>());
            }

            return(expression.Items
                   .SelectMany(arrayItemSyntax => GetExpressionAssignmentDiagnosticsInternal(
                                   typeManager,
                                   arrayItemSyntax.Value,
                                   targetType.ItemType,
                                   (expectedType, actualType, errorExpression) => DiagnosticBuilder.ForPosition(errorExpression).ArrayTypeMismatch(expectedType.Name, actualType.Name),
                                   skipConstantCheck,
                                   skipTypeErrors: true)));
        }
Esempio n. 19
0
        public void Validate(DecoratorSyntax decoratorSyntax, TypeSymbol targetType, ITypeManager typeManager, IDiagnosticWriter diagnosticWriter)
        {
            if (targetType is ErrorType)
            {
                return;
            }

            if (this.validator != null)
            {
                this.validator.Invoke(this.Overload.Name, decoratorSyntax, targetType, typeManager, diagnosticWriter);

                return;
            }

            // No custom validator provided. Just validate the target type.
            if (!this.CanAttachTo(targetType))
            {
                diagnosticWriter.Write(DiagnosticBuilder.ForPosition(decoratorSyntax).CannotAttacheDecoratorToTarget(this.Overload.Name, attachableType, targetType));
            }
        }
Esempio n. 20
0
        private static void GetArrayAssignmentDiagnostics(ITypeManager typeManager, ArraySyntax expression, ArrayType targetType, IList <Diagnostic> diagnostics, bool skipConstantCheck)
        {
            // if we have parse errors, no need to check assignability
            // we should not return the parse errors however because they will get double collected
            if (expression.HasParseErrors())
            {
                return;
            }

            foreach (var arrayItemSyntax in expression.Items)
            {
                GetExpressionAssignmentDiagnosticsInternal(
                    typeManager,
                    arrayItemSyntax.Value,
                    targetType.Item.Type,
                    diagnostics,
                    (expectedType, actualType, errorExpression) => DiagnosticBuilder.ForPosition(errorExpression).ArrayTypeMismatch(expectedType.Name, actualType.Name),
                    skipConstantCheck,
                    skipTypeErrors: true);
            }
        }
Esempio n. 21
0
        private static TypeSymbol NarrowObjectType(ITypeManager typeManager, ObjectSyntax expression, ObjectType targetType, IDiagnosticWriter diagnosticWriter, bool skipConstantCheck)
        {
            // TODO: Short-circuit on any object to avoid unnecessary processing?
            // TODO: Consider doing the schema check even if there are parse errors
            // if we have parse errors, there's no point to check assignability
            // we should not return the parse errors however because they will get double collected
            if (expression.HasParseErrors())
            {
                return(targetType);
            }

            var namedPropertyMap = expression.ToNamedPropertyDictionary();

            var missingRequiredProperties = targetType.Properties.Values
                                            .Where(p => p.Flags.HasFlag(TypePropertyFlags.Required) && !namedPropertyMap.ContainsKey(p.Name))
                                            .Select(p => p.Name)
                                            .OrderBy(p => p);

            if (missingRequiredProperties.Any())
            {
                IPositionable positionable = expression;
                string        blockName    = "object";

                var parent = typeManager.GetParent(expression);
                if (parent is ObjectPropertySyntax objectPropertyParent)
                {
                    positionable = objectPropertyParent.Key;
                    blockName    = "object";
                }
                else if (parent is INamedDeclarationSyntax declarationParent)
                {
                    positionable = declarationParent.Name;
                    blockName    = declarationParent.Keyword.Text;
                }

                diagnosticWriter.Write(DiagnosticBuilder.ForPosition(positionable).MissingRequiredProperties(ShouldWarn(targetType), missingRequiredProperties, blockName));
            }

            var narrowedProperties = new List <TypeProperty>();

            foreach (var declaredProperty in targetType.Properties.Values)
            {
                if (namedPropertyMap.TryGetValue(declaredProperty.Name, out var declaredPropertySyntax))
                {
                    bool skipConstantCheckForProperty = skipConstantCheck;

                    // is the property marked as requiring compile-time constants and has the parent already validated this?
                    if (skipConstantCheck == false && declaredProperty.Flags.HasFlag(TypePropertyFlags.Constant))
                    {
                        // validate that values are compile-time constants
                        GetCompileTimeConstantViolation(declaredPropertySyntax.Value, diagnosticWriter);

                        // disable compile-time constant validation for children
                        skipConstantCheckForProperty = true;
                    }

                    if (declaredProperty.Flags.HasFlag(TypePropertyFlags.ReadOnly))
                    {
                        // the declared property is read-only
                        // value cannot be assigned to a read-only property
                        diagnosticWriter.Write(DiagnosticBuilder.ForPosition(declaredPropertySyntax.Key).CannotAssignToReadOnlyProperty(ShouldWarn(targetType), declaredProperty.Name));
                        narrowedProperties.Add(new TypeProperty(declaredProperty.Name, declaredProperty.TypeReference.Type, declaredProperty.Flags));
                        continue;
                    }

                    // declared property is specified in the value object
                    // validate type
                    var narrowedType = NarrowTypeInternal(
                        typeManager,
                        declaredPropertySyntax.Value,
                        declaredProperty.TypeReference.Type,
                        diagnosticWriter,
                        GetPropertyMismatchErrorFactory(ShouldWarn(targetType), declaredProperty.Name),
                        skipConstantCheckForProperty,
                        skipTypeErrors: true);

                    narrowedProperties.Add(new TypeProperty(declaredProperty.Name, narrowedType, declaredProperty.Flags));
                }
                else
                {
                    narrowedProperties.Add(declaredProperty);
                }
            }

            // find properties that are specified on in the expression object but not declared in the schema
            var extraProperties = expression.Properties
                                  .Where(p => !(p.TryGetKeyText() is string keyName) || !targetType.Properties.ContainsKey(keyName));

            if (targetType.AdditionalPropertiesType == null)
            {
                bool shouldWarn = ShouldWarn(targetType);
                var  validUnspecifiedProperties = targetType.Properties.Values
                                                  .Where(p => !p.Flags.HasFlag(TypePropertyFlags.ReadOnly) && !namedPropertyMap.ContainsKey(p.Name))
                                                  .Select(p => p.Name)
                                                  .OrderBy(x => x);

                // extra properties are not allowed by the type
                foreach (var extraProperty in extraProperties)
                {
                    Diagnostic error;
                    var        builder = DiagnosticBuilder.ForPosition(extraProperty.Key);

                    if (extraProperty.TryGetKeyText() is string keyName)
                    {
                        error = validUnspecifiedProperties.Any() switch
                        {
                            true => SpellChecker.GetSpellingSuggestion(keyName, validUnspecifiedProperties) switch
                            {
                                string suggestedKeyName when suggestedKeyName != null
                                => builder.DisallowedPropertyWithSuggestion(shouldWarn, keyName, targetType, suggestedKeyName),
                                _ => builder.DisallowedPropertyWithPermissibleProperties(shouldWarn, keyName, targetType, validUnspecifiedProperties)
                            },
Esempio n. 22
0
 public SemanticModel(FileSymbol root, ITypeManager typeManager, IDictionary <SyntaxBase, Symbol> bindings)
 {
     this.Root        = root;
     this.typeManager = typeManager;
     this.bindings    = bindings.ToImmutableDictionary();
 }
Esempio n. 23
0
 public TypeSymbol GetAssignedType(ITypeManager typeManager, ArraySyntax?allowedSyntax)
 {
Esempio n. 24
0
 public SymbolContext(ITypeManager typeManager, IReadOnlyDictionary <SyntaxBase, Symbol> bindings, Compilation compilation)
 {
     this.typeManager = typeManager;
     this.bindings    = bindings;
     this.compilation = compilation;
 }
Esempio n. 25
0
 private TypeValidator(ITypeManager typeManager, IBinder binder, IDiagnosticWriter diagnosticWriter)
 {
     this.typeManager      = typeManager;
     this.binder           = binder;
     this.diagnosticWriter = diagnosticWriter;
 }
Esempio n. 26
0
 public BDDSuiteBuilder(IReflectionProvider reflectionProvider, ITypeManager typeManager)
     : base()
 {
     _reflectionProvider = reflectionProvider;
     _typeManager = typeManager;
 }
Esempio n. 27
0
        private static void GetObjectAssignmentDiagnostics(ITypeManager typeManager, ObjectSyntax expression, ObjectType targetType, IList <Diagnostic> diagnostics, bool skipConstantCheck)
        {
            // TODO: Short-circuit on any object to avoid unnecessary processing?
            // TODO: Consider doing the schema check even if there are parse errors
            // if we have parse errors, there's no point to check assignability
            // we should not return the parse errors however because they will get double collected
            if (expression.HasParseErrors())
            {
                return;
            }

            var propertyMap = expression.ToPropertyDictionary();

            var missingRequiredProperties = targetType.Properties.Values
                                            .Where(p => p.Flags.HasFlag(TypePropertyFlags.Required) && propertyMap.ContainsKey(p.Name) == false)
                                            .Select(p => p.Name)
                                            .OrderBy(p => p)
                                            .ConcatString(LanguageConstants.ListSeparator);

            if (string.IsNullOrEmpty(missingRequiredProperties) == false)
            {
                diagnostics.Add(DiagnosticBuilder.ForPosition(expression).MissingRequiredProperties(missingRequiredProperties));
            }

            foreach (var declaredProperty in targetType.Properties.Values)
            {
                if (propertyMap.TryGetValue(declaredProperty.Name, out var declaredPropertySyntax))
                {
                    bool skipConstantCheckForProperty = skipConstantCheck;

                    // is the property marked as requiring compile-time constants and has the parent already validated this?
                    if (skipConstantCheck == false && declaredProperty.Flags.HasFlag(TypePropertyFlags.Constant))
                    {
                        // validate that values are compile-time constants
                        diagnostics.AddRange(GetCompileTimeConstantViolation(declaredPropertySyntax.Value));

                        // disable compile-time constant validation for children
                        skipConstantCheckForProperty = true;
                    }

                    if (declaredProperty.Flags.HasFlag(TypePropertyFlags.ReadOnly))
                    {
                        // the declared property is read-only
                        // value cannot be assigned to a read-only property
                        diagnostics.Add(DiagnosticBuilder.ForPosition(declaredPropertySyntax.Key).CannotAssignToReadOnlyProperty(declaredProperty.Name));
                    }

                    // declared property is specified in the value object
                    // validate type
                    GetExpressionAssignmentDiagnosticsInternal(
                        typeManager,
                        declaredPropertySyntax.Value,
                        declaredProperty.TypeReference.Type,
                        diagnostics,
                        (expectedType, actualType, errorExpression) => DiagnosticBuilder.ForPosition(errorExpression).PropertyTypeMismatch(declaredProperty.Name, expectedType, actualType),
                        skipConstantCheckForProperty,
                        skipTypeErrors: true);
                }
            }

            // find properties that are specified on in the expression object but not declared in the schema
            var extraProperties = expression.Properties
                                  .Select(p => p.GetKeyText())
                                  .Except(targetType.Properties.Values.Select(p => p.Name), LanguageConstants.IdentifierComparer)
                                  .Select(name => propertyMap[name]);

            if (targetType.AdditionalPropertiesType == null)
            {
                var validUnspecifiedProperties = targetType.Properties.Values
                                                 .Where(p => !p.Flags.HasFlag(TypePropertyFlags.ReadOnly))
                                                 .Select(p => p.Name)
                                                 .Except(expression.Properties.Select(p => p.GetKeyText()), LanguageConstants.IdentifierComparer)
                                                 .OrderBy(x => x);

                // extra properties are not allowed by the type
                foreach (var extraProperty in extraProperties)
                {
                    var error = validUnspecifiedProperties.Any() ?
                                DiagnosticBuilder.ForPosition(extraProperty.Key).DisallowedPropertyWithPermissibleProperties(extraProperty.GetKeyText(), targetType.Name, validUnspecifiedProperties) :
                                DiagnosticBuilder.ForPosition(extraProperty.Key).DisallowedProperty(extraProperty.GetKeyText(), targetType.Name);

                    diagnostics.AddRange(error.AsEnumerable());
                }
            }
            else
            {
                // extra properties must be assignable to the right type
                foreach (ObjectPropertySyntax extraProperty in extraProperties)
                {
                    bool skipConstantCheckForProperty = skipConstantCheck;

                    // is the property marked as requiring compile-time constants and has the parent already validated this?
                    if (skipConstantCheckForProperty == false && targetType.AdditionalPropertiesFlags.HasFlag(TypePropertyFlags.Constant))
                    {
                        // validate that values are compile-time constants
                        diagnostics.AddRange(GetCompileTimeConstantViolation(extraProperty.Value));

                        // disable compile-time constant validation for children
                        skipConstantCheckForProperty = true;
                    }

                    GetExpressionAssignmentDiagnosticsInternal(
                        typeManager,
                        extraProperty.Value,
                        targetType.AdditionalPropertiesType.Type,
                        diagnostics,
                        (expectedType, actualType, errorExpression) => DiagnosticBuilder.ForPosition(errorExpression).PropertyTypeMismatch(extraProperty.GetKeyText(), expectedType, actualType),
                        skipConstantCheckForProperty,
                        skipTypeErrors: true);
                }
            }
        }
Esempio n. 28
0
 public TestDescriber(ITestDescriptionWriter testDescriptionWriter, ITypeManager typeManager)
 {
     _testDescriptionWriter = testDescriptionWriter;
     _typeManager = typeManager;
 }
Esempio n. 29
0
 internal static void Initialize(ITypeManager instance)
 {
     _instance = instance;
 }
Esempio n. 30
0
        private static TypeSymbol NarrowDiscriminatedObjectType(ITypeManager typeManager, ObjectSyntax expression, DiscriminatedObjectType targetType, IDiagnosticWriter diagnosticWriter, bool skipConstantCheck)
        {
            // if we have parse errors, there's no point to check assignability
            // we should not return the parse errors however because they will get double collected
            if (expression.HasParseErrors())
            {
                return(LanguageConstants.Any);
            }

            var discriminatorProperty = expression.Properties.FirstOrDefault(x => LanguageConstants.IdentifierComparer.Equals(x.TryGetKeyText(), targetType.DiscriminatorKey));

            if (discriminatorProperty == null)
            {
                // object doesn't contain the discriminator field
                diagnosticWriter.Write(DiagnosticBuilder.ForPosition(expression).MissingRequiredProperty(ShouldWarn(targetType), targetType.DiscriminatorKey, targetType.DiscriminatorKeysUnionType));

                var propertyKeys = expression.Properties
                                   .Select(x => x.TryGetKeyText())
                                   .Where(key => !string.IsNullOrEmpty(key))
                                   .Select(key => key !);

                // do a reverse lookup to check if there's any misspelled discriminator key
                var misspelledDiscriminatorKey = SpellChecker.GetSpellingSuggestion(targetType.DiscriminatorKey, propertyKeys);

                if (misspelledDiscriminatorKey != null)
                {
                    diagnosticWriter.Write(DiagnosticBuilder.ForPosition(expression).DisallowedPropertyWithSuggestion(ShouldWarn(targetType), misspelledDiscriminatorKey, targetType.DiscriminatorKeysUnionType, targetType.DiscriminatorKey));
                }


                return(LanguageConstants.Any);
            }

            // At some point in the future we may want to relax the expectation of a string literal key, and allow a generic string.
            // In this case, the best we can do is validate against the union of all the settable properties.
            // Let's not do this just yet, and see if a use-case arises.

            var discriminatorType = typeManager.GetTypeInfo(discriminatorProperty.Value);

            if (!(discriminatorType is StringLiteralType stringLiteralDiscriminator))
            {
                diagnosticWriter.Write(DiagnosticBuilder.ForPosition(expression).PropertyTypeMismatch(ShouldWarn(targetType), targetType.DiscriminatorKey, targetType.DiscriminatorKeysUnionType, discriminatorType));
                return(LanguageConstants.Any);
            }

            if (!targetType.UnionMembersByKey.TryGetValue(stringLiteralDiscriminator.Name, out var selectedObjectReference))
            {
                // no matches
                var    discriminatorCandidates = targetType.UnionMembersByKey.Keys.OrderBy(x => x);
                string?suggestedDiscriminator  = SpellChecker.GetSpellingSuggestion(stringLiteralDiscriminator.Name, discriminatorCandidates);
                var    builder    = DiagnosticBuilder.ForPosition(discriminatorProperty.Value);
                bool   shouldWarn = ShouldWarn(targetType);

                diagnosticWriter.Write(suggestedDiscriminator != null
                    ? builder.PropertyStringLiteralMismatchWithSuggestion(shouldWarn, targetType.DiscriminatorKey, targetType.DiscriminatorKeysUnionType, stringLiteralDiscriminator.Name, suggestedDiscriminator)
                    : builder.PropertyTypeMismatch(shouldWarn, targetType.DiscriminatorKey, targetType.DiscriminatorKeysUnionType, discriminatorType));

                return(LanguageConstants.Any);
            }

            if (!(selectedObjectReference.Type is ObjectType selectedObjectType))
            {
                throw new InvalidOperationException($"Discriminated type {targetType.Name} contains non-object member");
            }

            // we have a match!
            return(NarrowObjectType(typeManager, expression, selectedObjectType, diagnosticWriter, skipConstantCheck));
        }
Esempio n. 31
0
 public DeclaredTypeManager(IResourceTypeProvider resourceTypeProvider, TypeManager typeManager, IBinder binder)
 {
     this.resourceTypeProvider = resourceTypeProvider;
     this.typeManager          = typeManager;
     this.binder = binder;
 }
Esempio n. 32
0
 internal static void Initialize(ITypeManager instance)
 {
     _instance  = instance;
     _factories = new Dictionary <Type, TypeFactory>();
 }
 public HubSpotContactConnector(IHubSpotClient client, IContactTypeManager typeManager)
 {
     _client      = client ?? throw new ArgumentNullException(nameof(client));
     _typeManager = typeManager ?? throw new ArgumentNullException(nameof(typeManager));
 }
Esempio n. 34
0
        private static TypeSymbol NarrowObjectType(ITypeManager typeManager, ObjectSyntax expression, ObjectType targetType, IList <Diagnostic> diagnostics, bool skipConstantCheck)
        {
            // TODO: Short-circuit on any object to avoid unnecessary processing?
            // TODO: Consider doing the schema check even if there are parse errors
            // if we have parse errors, there's no point to check assignability
            // we should not return the parse errors however because they will get double collected
            if (expression.HasParseErrors())
            {
                return(targetType);
            }

            var namedPropertyMap = expression.ToNamedPropertyDictionary();

            var missingRequiredProperties = targetType.Properties.Values
                                            .Where(p => p.Flags.HasFlag(TypePropertyFlags.Required) && !namedPropertyMap.ContainsKey(p.Name))
                                            .Select(p => p.Name)
                                            .OrderBy(p => p)
                                            .ConcatString(LanguageConstants.ListSeparator);

            if (string.IsNullOrEmpty(missingRequiredProperties) == false)
            {
                diagnostics.Add(DiagnosticBuilder.ForPosition(expression).MissingRequiredProperties(ShouldWarn(targetType), missingRequiredProperties));
            }

            var narrowedProperties = new List <TypeProperty>();

            foreach (var declaredProperty in targetType.Properties.Values)
            {
                if (namedPropertyMap.TryGetValue(declaredProperty.Name, out var declaredPropertySyntax))
                {
                    bool skipConstantCheckForProperty = skipConstantCheck;

                    // is the property marked as requiring compile-time constants and has the parent already validated this?
                    if (skipConstantCheck == false && declaredProperty.Flags.HasFlag(TypePropertyFlags.Constant))
                    {
                        // validate that values are compile-time constants
                        diagnostics.AddRange(GetCompileTimeConstantViolation(declaredPropertySyntax.Value));

                        // disable compile-time constant validation for children
                        skipConstantCheckForProperty = true;
                    }

                    if (declaredProperty.Flags.HasFlag(TypePropertyFlags.ReadOnly))
                    {
                        // the declared property is read-only
                        // value cannot be assigned to a read-only property
                        diagnostics.Add(DiagnosticBuilder.ForPosition(declaredPropertySyntax.Key).CannotAssignToReadOnlyProperty(ShouldWarn(targetType), declaredProperty.Name));
                    }

                    // declared property is specified in the value object
                    // validate type
                    var narrowedType = NarrowTypeInternal(
                        typeManager,
                        declaredPropertySyntax.Value,
                        declaredProperty.TypeReference.Type,
                        diagnostics,
                        (expectedType, actualType, errorExpression) => DiagnosticBuilder.ForPosition(errorExpression).PropertyTypeMismatch(ShouldWarn(targetType), declaredProperty.Name, expectedType, actualType),
                        skipConstantCheckForProperty,
                        skipTypeErrors: true);

                    narrowedProperties.Add(new TypeProperty(declaredProperty.Name, narrowedType, declaredProperty.Flags));
                }
                else
                {
                    narrowedProperties.Add(declaredProperty);
                }
            }

            // find properties that are specified on in the expression object but not declared in the schema
            var extraProperties = expression.Properties
                                  .Where(p => !(p.TryGetKeyText() is string keyName) || !targetType.Properties.ContainsKey(keyName));

            if (targetType.AdditionalPropertiesType == null)
            {
                var validUnspecifiedProperties = targetType.Properties.Values
                                                 .Where(p => !p.Flags.HasFlag(TypePropertyFlags.ReadOnly))
                                                 .Where(p => !namedPropertyMap.ContainsKey(p.Name))
                                                 .Select(p => p.Name)
                                                 .OrderBy(x => x);

                // extra properties are not allowed by the type
                foreach (var extraProperty in extraProperties)
                {
                    Diagnostic error;
                    if (extraProperty.TryGetKeyText() is string keyName)
                    {
                        error = validUnspecifiedProperties.Any() ?
                                DiagnosticBuilder.ForPosition(extraProperty.Key).DisallowedPropertyWithPermissibleProperties(ShouldWarn(targetType), keyName, targetType.Name, validUnspecifiedProperties) :
                                DiagnosticBuilder.ForPosition(extraProperty.Key).DisallowedProperty(ShouldWarn(targetType), keyName, targetType.Name);
                    }
                    else
                    {
                        error = validUnspecifiedProperties.Any() ?
                                DiagnosticBuilder.ForPosition(extraProperty.Key).DisallowedInterpolatedKeyPropertyWithPermissibleProperties(ShouldWarn(targetType), targetType.Name, validUnspecifiedProperties) :
                                DiagnosticBuilder.ForPosition(extraProperty.Key).DisallowedInterpolatedKeyProperty(ShouldWarn(targetType), targetType.Name);
                    }

                    diagnostics.AddRange(error.AsEnumerable());
                }
            }
            else
            {
                // extra properties must be assignable to the right type
                foreach (ObjectPropertySyntax extraProperty in extraProperties)
                {
                    bool skipConstantCheckForProperty = skipConstantCheck;

                    // is the property marked as requiring compile-time constants and has the parent already validated this?
                    if (skipConstantCheckForProperty == false && targetType.AdditionalPropertiesFlags.HasFlag(TypePropertyFlags.Constant))
                    {
                        // validate that values are compile-time constants
                        diagnostics.AddRange(GetCompileTimeConstantViolation(extraProperty.Value));

                        // disable compile-time constant validation for children
                        skipConstantCheckForProperty = true;
                    }

                    TypeMismatchErrorFactory typeMismatchErrorFactory;
                    if (extraProperty.TryGetKeyText() is string keyName)
                    {
                        typeMismatchErrorFactory = (expectedType, actualType, errorExpression) => DiagnosticBuilder.ForPosition(errorExpression).PropertyTypeMismatch(ShouldWarn(targetType), keyName, expectedType, actualType);
                    }
                    else
                    {
                        typeMismatchErrorFactory = (expectedType, actualType, errorExpression) => DiagnosticBuilder.ForPosition(errorExpression).ExpectedValueTypeMismatch(ShouldWarn(targetType), expectedType, actualType);
                    }

                    var narrowedProperty = NarrowTypeInternal(
                        typeManager,
                        extraProperty.Value,
                        targetType.AdditionalPropertiesType.Type,
                        diagnostics,
                        typeMismatchErrorFactory,
                        skipConstantCheckForProperty,
                        skipTypeErrors: true);

                    // TODO should we try and narrow the additional properties type? May be difficult
                }
            }

            return(new NamedObjectType(targetType.Name, targetType.ValidationFlags, narrowedProperties, targetType.AdditionalPropertiesType, targetType.AdditionalPropertiesFlags));
        }