コード例 #1
0
 public static void WriteMultiple(this IDiagnosticWriter diagnosticWriter, IEnumerable <Diagnostic> diagnostics)
 {
     foreach (var diagnostic in diagnostics)
     {
         diagnosticWriter.Write(diagnostic);
     }
 }
コード例 #2
0
        public static void Validate(ProgramSyntax programSyntax, IDiagnosticWriter diagnosticWriter)
        {
            var visitor = new IntegerValidatorVisitor(diagnosticWriter);

            // visiting writes diagnostics in some cases
            visitor.Visit(programSyntax);
        }
コード例 #3
0
        private static void DetectDuplicateNames(SemanticModel semanticModel, IDiagnosticWriter diagnosticWriter, ImmutableDictionary <ResourceMetadata, ScopeHelper.ScopeData> resourceScopeData, ImmutableDictionary <ModuleSymbol, ScopeHelper.ScopeData> moduleScopeData)
        {
            // This method only checks, if in one deployment we do not have 2 or more resources with this same name in one deployment to avoid template validation error
            // This will not check resource constraints such as necessity of having unique virtual network names within resource group

            var duplicateResources = GetResourceDefinitions(semanticModel, resourceScopeData)
                                     .GroupBy(x => x, ResourceDefinition.EqualityComparer)
                                     .Where(group => group.Count() > 1);

            foreach (var duplicatedResourceGroup in duplicateResources)
            {
                var duplicatedResourceNames = duplicatedResourceGroup.Select(x => x.ResourceName).ToArray();
                foreach (var duplicatedResource in duplicatedResourceGroup)
                {
                    diagnosticWriter.Write(duplicatedResource.ResourceNamePropertyValue, x => x.ResourceMultipleDeclarations(duplicatedResourceNames));
                }
            }

            var duplicateModules = GetModuleDefinitions(semanticModel, moduleScopeData)
                                   .GroupBy(x => x, ModuleDefinition.EqualityComparer)
                                   .Where(group => group.Count() > 1);

            foreach (var duplicatedModuleGroup in duplicateModules)
            {
                var duplicatedModuleNames = duplicatedModuleGroup.Select(x => x.ModuleName).ToArray();
                foreach (var duplicatedModule in duplicatedModuleGroup)
                {
                    diagnosticWriter.Write(duplicatedModule.ModulePropertyNameValue, x => x.ModuleMultipleDeclarations(duplicatedModuleNames));
                }
            }
        }
コード例 #4
0
        public static void Validate(SemanticModel semanticModel, IDiagnosticWriter diagnosticWriter)
        {
            var visitor = new ForSyntaxValidatorVisitor(semanticModel, diagnosticWriter);

            // visiting writes diagnostics in some cases
            visitor.Visit(semanticModel.SourceFile.ProgramSyntax);
        }
コード例 #5
0
ファイル: TypeValidator.cs プロジェクト: Sheelnidhi-g/bicep
        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
            })
コード例 #6
0
 public DeployTimeConstantViolationVisitor(
     SyntaxBase deployTimeConstantContainer,
     SemanticModel semanticModel,
     IDiagnosticWriter diagnosticWriter)
 {
     this.DeployTimeConstantContainer = deployTimeConstantContainer;
     this.SemanticModel    = semanticModel;
     this.DiagnosticWriter = diagnosticWriter;
 }
コード例 #7
0
 public DeployTimeConstantViolationVisitor(
     SyntaxBase deployTimeConstantContainer,
     SemanticModel semanticModel,
     IDiagnosticWriter diagnosticWriter,
     Dictionary <DeclaredSymbol, ObjectType> existingResourceBodyObjectTypeOverrides)
 {
     this.DeployTimeConstantContainer = deployTimeConstantContainer;
     this.SemanticModel    = semanticModel;
     this.DiagnosticWriter = diagnosticWriter;
     this.ExistingResourceBodyObjectTypeOverrides = existingResourceBodyObjectTypeOverrides;
 }
コード例 #8
0
        // entry point for this visitor. We only iterate through modules and resources
        public static void ValidateDeployTimeConstants(SemanticModel model, IDiagnosticWriter diagnosticWriter)
        {
            var deploymentTimeConstantVisitor = new DeployTimeConstantVisitor(model, diagnosticWriter);

            foreach (var declaredSymbol in model.Root.ResourceDeclarations)
            {
                deploymentTimeConstantVisitor.Visit(declaredSymbol.DeclaringSyntax);
            }
            foreach (var declaredSymbol in model.Root.ModuleDeclarations)
            {
                deploymentTimeConstantVisitor.Visit(declaredSymbol.DeclaringSyntax);
            }
        }
コード例 #9
0
        public static void Validate(SemanticModel semanticModel, IDiagnosticWriter diagnosticWriter)
        {
            // Collect all sytnaxes that require DTCs (a.k.a. DTC containers).
            var containers = DeployTimeConstantContainerVisitor.CollectDeployTimeConstantContainers(semanticModel);

            foreach (var container in containers)
            {
                // Only visit child nodes of the DTC container to avoid flagging the DTC container itself.
                foreach (var childContainer in GetChildrenOfDeployTimeConstantContainer(semanticModel, container))
                {
                    // Validate property accesses, array accesses, resource accesses and function calls.
                    new DeployTimeConstantDirectViolationVisitor(container, semanticModel, diagnosticWriter)
                    .Visit(childContainer);

                    // Validate variable dependencies.
                    foreach (var variableDependency in VariableDependencyVisitor.GetVariableDependencies(semanticModel, childContainer))
                    {
                        new DeployTimeConstantIndirectViolationVisitor(container, variableDependency, semanticModel, diagnosticWriter)
                        .Visit(variableDependency);
                    }
                }
            }
        }
コード例 #10
0
ファイル: TypeValidator.cs プロジェクト: swipswaps/bicep
        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));
        }
コード例 #11
0
ファイル: TypeValidator.cs プロジェクト: swipswaps/bicep
        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));
        }
コード例 #12
0
 public Lexer(SlidingTextWindow textWindow, IDiagnosticWriter diagnosticWriter)
 {
     this.textWindow       = textWindow;
     this.diagnosticWriter = diagnosticWriter;
 }
コード例 #13
0
ファイル: TypeValidator.cs プロジェクト: swipswaps/bicep
        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));
        }
コード例 #14
0
ファイル: AzNamespaceSymbol.cs プロジェクト: rynowak/bicep
        private static ObjectType GetResourceGroupReturnType(IBinder binder, IFileResolver fileResolver, IDiagnosticWriter diagnostics, ImmutableArray <FunctionArgumentSyntax> arguments, ImmutableArray <TypeSymbol> argumentTypes)
        {
            var properties = new ObjectType("properties", TypeSymbolValidationFlags.Default, new[]
            {
                new TypeProperty("provisioningState", LanguageConstants.String),
            }, null);

            return(new ResourceGroupScopeType(arguments, new[]
            {
                new TypeProperty("id", LanguageConstants.String),
                new TypeProperty("name", LanguageConstants.String),
                new TypeProperty("type", LanguageConstants.String),
                new TypeProperty("location", LanguageConstants.String),
                new TypeProperty("managedBy", LanguageConstants.String),
                new TypeProperty("tags", LanguageConstants.Tags),
                new TypeProperty("properties", properties),
            }));
        }
コード例 #15
0
ファイル: AzNamespaceSymbol.cs プロジェクト: rynowak/bicep
 private static ObjectType GetSubscriptionReturnType(IBinder binder, IFileResolver fileResolver, IDiagnosticWriter diagnostics, ImmutableArray <FunctionArgumentSyntax> arguments, ImmutableArray <TypeSymbol> argumentTypes)
 {
     return(new SubscriptionScopeType(arguments, new[]
     {
         new TypeProperty("id", LanguageConstants.String),
         new TypeProperty("subscriptionId", LanguageConstants.String),
         new TypeProperty("tenantId", LanguageConstants.String),
         new TypeProperty("displayName", LanguageConstants.String),
     }));
 }
コード例 #16
0
 private ForSyntaxValidatorVisitor(SemanticModel semanticModel, IDiagnosticWriter diagnosticWriter)
 {
     this.semanticModel    = semanticModel;
     this.diagnosticWriter = diagnosticWriter;
 }
コード例 #17
0
        private static TypeSymbol LoadContentAsBase64TypeBuilder(IBinder binder, IFileResolver fileResolver, IDiagnosticWriter diagnostics, ImmutableArray <FunctionArgumentSyntax> arguments, ImmutableArray <TypeSymbol> argumentTypes)
        {
            if (argumentTypes[0] is not StringLiteralType filePathType)
            {
                diagnostics.Write(DiagnosticBuilder.ForPosition(arguments[0]).CompileTimeConstantRequired());
                return(LanguageConstants.String);
            }
            var filePathValue = filePathType.RawStringValue;

            var fileUri = GetFileUriWithDiagnostics(binder, fileResolver, diagnostics, filePathValue, arguments[0]);

            if (fileUri is null)
            {
                return(LanguageConstants.String);
            }
            if (!fileResolver.TryReadAsBase64(fileUri, out var fileContent, out var fileReadFailureBuilder, LanguageConstants.MaxLiteralCharacterLimit))
            {
                diagnostics.Write(fileReadFailureBuilder.Invoke(DiagnosticBuilder.ForPosition(arguments[0])));
                return(LanguageConstants.String);
            }

            return(new StringLiteralType(binder.FileSymbol.FileUri.MakeRelativeUri(fileUri).ToString(), fileContent));
        }
コード例 #18
0
ファイル: TypeValidator.cs プロジェクト: husains/bicep
 private TypeValidator(ITypeManager typeManager, IBinder binder, IDiagnosticWriter diagnosticWriter)
 {
     this.typeManager      = typeManager;
     this.binder           = binder;
     this.diagnosticWriter = diagnosticWriter;
 }
コード例 #19
0
 public static void Write(this IDiagnosticWriter diagnosticWriter, IPositionable positionable, DiagnosticBuilder.DiagnosticBuilderDelegate buildDiagnosticFunc)
 => diagnosticWriter.Write(buildDiagnosticFunc(DiagnosticBuilder.ForPosition(positionable)));
コード例 #20
0
        public static ImmutableDictionary <ModuleSymbol, ScopeHelper.ScopeData> GetSupportedScopeInfo(SemanticModel semanticModel, IDiagnosticWriter diagnosticWriter)
        {
            var moduleScopeData = new Dictionary <ModuleSymbol, ScopeHelper.ScopeData>();

            foreach (var moduleSymbol in semanticModel.Root.ModuleDeclarations)
            {
                var scopeValue = moduleSymbol.SafeGetBodyPropertyValue(LanguageConstants.ResourceScopePropertyName);
                if (scopeValue == null)
                {
                    // no scope provided - assume the parent scope
                    moduleScopeData[moduleSymbol] = new ScopeHelper.ScopeData {
                        RequestedScope = semanticModel.TargetScope
                    };
                    continue;
                }

                var scopeType = semanticModel.GetTypeInfo(scopeValue);
                var scopeData = ScopeHelper.TryGetScopeData(semanticModel.TargetScope, scopeType);

                if (scopeData != null)
                {
                    moduleScopeData[moduleSymbol] = scopeData;
                    continue;
                }

                switch (semanticModel.TargetScope)
                {
                case ResourceScopeType.TenantScope:
                    diagnosticWriter.Write(scopeValue, x => x.InvalidModuleScopeForTenantScope());
                    break;

                case ResourceScopeType.ManagementGroupScope:
                    diagnosticWriter.Write(scopeValue, x => x.InvalidModuleScopeForManagementScope());
                    break;

                case ResourceScopeType.SubscriptionScope:
                    diagnosticWriter.Write(scopeValue, x => x.InvalidModuleScopeForSubscriptionScope());
                    break;

                case ResourceScopeType.ResourceGroupScope:
                    diagnosticWriter.Write(scopeValue, x => x.InvalidModuleScopeForResourceGroup());
                    break;

                default:
                    throw new InvalidOperationException($"Unrecognized target scope {semanticModel.TargetScope}");
                }
            }

            return(moduleScopeData.ToImmutableDictionary());
        }
コード例 #21
0
        public static ImmutableDictionary <ResourceSymbol, ResourceSymbol?> GetResoureScopeInfo(SemanticModel semanticModel, IDiagnosticWriter diagnosticWriter)
        {
            var scopeInfo = new Dictionary <ResourceSymbol, ResourceSymbol?>();

            foreach (var resourceSymbol in semanticModel.Root.ResourceDeclarations)
            {
                var scopeValue = resourceSymbol.SafeGetBodyPropertyValue(LanguageConstants.ResourceScopePropertyName);
                if (scopeValue is null)
                {
                    scopeInfo[resourceSymbol] = null;
                    continue;
                }

                var scopeSymbol = semanticModel.GetSymbolInfo(scopeValue);
                if (scopeSymbol is not ResourceSymbol targetResourceSymbol)
                {
                    scopeInfo[resourceSymbol] = null;
                    diagnosticWriter.Write(scopeValue, x => x.InvalidExtensionResourceScope());
                    continue;
                }

                scopeInfo[resourceSymbol] = targetResourceSymbol;
            }

            return(scopeInfo.ToImmutableDictionary());
        }
コード例 #22
0
 private static TypeSymbol JsonTypeBuilder(IBinder binder, IFileResolver fileResolver, IDiagnosticWriter diagnostics, ImmutableArray <FunctionArgumentSyntax> arguments, ImmutableArray <TypeSymbol> argumentTypes)
 {
コード例 #23
0
ファイル: TypeValidator.cs プロジェクト: swipswaps/bicep
        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)
                            },
コード例 #24
0
        private static Uri?GetFileUriWithDiagnostics(IBinder binder, IFileResolver fileResolver, IDiagnosticWriter diagnostics, string filePath, SyntaxBase filePathArgument)
        {
            if (!LocalModuleReference.Validate(filePath, out var validateFilePathFailureBuilder))
            {
                diagnostics.Write(validateFilePathFailureBuilder.Invoke(DiagnosticBuilder.ForPosition(filePathArgument)));
                return(null);
            }

            var fileUri = fileResolver.TryResolveFilePath(binder.FileSymbol.FileUri, filePath);

            if (fileUri is null)
            {
                diagnostics.Write(DiagnosticBuilder.ForPosition(filePathArgument).FilePathCouldNotBeResolved(filePath, binder.FileSymbol.FileUri.LocalPath));
                return(null);
            }

            if (!fileUri.IsFile)
            {
                diagnostics.Write(DiagnosticBuilder.ForPosition(filePathArgument).UnableToLoadNonFileUri(fileUri));
                return(null);
            }
            return(fileUri);
        }
コード例 #25
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));
            }

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

                return;
            }
        }
コード例 #26
0
        private static TypeSymbol LoadTextContentTypeBuilder(IBinder binder, IFileResolver fileResolver, IDiagnosticWriter diagnostics, ImmutableArray <FunctionArgumentSyntax> arguments, ImmutableArray <TypeSymbol> argumentTypes)
        {
            if (argumentTypes[0] is not StringLiteralType filePathType)
            {
                diagnostics.Write(DiagnosticBuilder.ForPosition(arguments[0]).CompileTimeConstantRequired());
                return(LanguageConstants.String);
            }
            var filePathValue = filePathType.RawStringValue;

            var fileUri = GetFileUriWithDiagnostics(binder, fileResolver, diagnostics, filePathValue, arguments[0]);

            if (fileUri is null)
            {
                return(LanguageConstants.String);
            }
            var fileEncoding = Encoding.UTF8;

            if (argumentTypes.Length > 1)
            {
                if (argumentTypes[1] is not StringLiteralType encodingType)
                {
                    diagnostics.Write(DiagnosticBuilder.ForPosition(arguments[1]).CompileTimeConstantRequired());
                    return(LanguageConstants.String);
                }
                fileEncoding = LanguageConstants.SupportedEncodings.First(x => string.Equals(x.name, encodingType.RawStringValue, LanguageConstants.IdentifierComparison)).encoding;
            }

            if (!fileResolver.TryRead(fileUri, out var fileContent, out var fileReadFailureBuilder, fileEncoding, LanguageConstants.MaxLiteralCharacterLimit, out var detectedEncoding))
            {
                diagnostics.Write(fileReadFailureBuilder.Invoke(DiagnosticBuilder.ForPosition(arguments[0])));
                return(LanguageConstants.String);
            }
            if (arguments.Length > 1 && fileEncoding != detectedEncoding)
            {
                diagnostics.Write(DiagnosticBuilder.ForPosition(arguments[1]).FileEncodingMismatch(detectedEncoding.WebName));
            }
            return(new StringLiteralType(fileContent));
        }
コード例 #27
0
ファイル: Decorator.cs プロジェクト: swipswaps/bicep
        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);
        }
コード例 #28
0
ファイル: AzNamespaceSymbol.cs プロジェクト: rynowak/bicep
 private static ObjectType GetRestrictedTenantReturnType(IBinder binder, IFileResolver fileResolver, IDiagnosticWriter diagnostics, ImmutableArray <FunctionArgumentSyntax> arguments, ImmutableArray <TypeSymbol> argumentTypes)
 => new TenantScopeType(arguments, Enumerable.Empty <TypeProperty>());
コード例 #29
0
ファイル: TypeValidator.cs プロジェクト: husains/bicep
        /// <summary>
        /// Gets the list of compile-time constant violations. An error is logged for every occurrence of an expression that is not entirely composed of literals.
        /// It may return inaccurate results for malformed trees.
        /// </summary>
        /// <param name="expression">the expression to check for compile-time constant violations</param>
        /// <param name="diagnosticWriter">Diagnostic writer instance</param>
        public static void GetCompileTimeConstantViolation(SyntaxBase expression, IDiagnosticWriter diagnosticWriter)
        {
            var visitor = new CompileTimeConstantVisitor(diagnosticWriter);

            visitor.Visit(expression);
        }
コード例 #30
0
 private DeployTimeConstantVisitor(SemanticModel model, IDiagnosticWriter diagnosticWriter)
 {
     this.model            = model;
     this.diagnosticWriter = diagnosticWriter;
 }