Ejemplo n.º 1
0
        private DeclaredTypeAssignment?GetObjectPropertyType(TypeSymbol?type, ObjectSyntax?objectSyntax, string propertyName, bool useSyntax)
        {
            // local function
            DeclaredTypeFlags ConvertFlags(TypePropertyFlags flags) => flags.HasFlag(TypePropertyFlags.Constant) ? DeclaredTypeFlags.Constant : DeclaredTypeFlags.None;

            // the declared types on the declaration side of things will take advantage of properties
            // set on objects to resolve discriminators at all levels
            // to take advantage of this, we should first try looking up the property's declared type
            var declaringProperty = objectSyntax?.SafeGetPropertyByName(propertyName);

            if (useSyntax && declaringProperty != null)
            {
                // it is important to get the property value's decl type instead of the property's decl type
                // (the property has the unresolved discriminated object type and the value will have it resolved)
                var declaredPropertyAssignment = this.GetDeclaredTypeAssignment(declaringProperty.Value);
                if (declaredPropertyAssignment != null)
                {
                    return(declaredPropertyAssignment);
                }
            }

            // could not get the declared type via syntax
            // let's use the type info instead
            switch (type)
            {
            case ObjectType objectType:
                // lookup declared property
                if (objectType.Properties.TryGetValue(propertyName, out var property))
                {
                    return(new DeclaredTypeAssignment(property.TypeReference.Type, declaringProperty, ConvertFlags(property.Flags)));
                }

                // if there are additional properties, try those
                if (objectType.AdditionalPropertiesType != null)
                {
                    return(new DeclaredTypeAssignment(objectType.AdditionalPropertiesType.Type, declaringProperty, ConvertFlags(objectType.AdditionalPropertiesFlags)));
                }

                break;

            case DiscriminatedObjectType discriminated:
                if (string.Equals(propertyName, discriminated.DiscriminatorProperty.Name, LanguageConstants.IdentifierComparison))
                {
                    // the property is the discriminator property - use its type
                    return(new DeclaredTypeAssignment(discriminated.DiscriminatorProperty.TypeReference.Type, declaringProperty));
                }

                break;
            }

            return(null);
        }
Ejemplo n.º 2
0
            private void VisitResourceOrModuleDeclaration(SyntaxBase declaringSyntax, ObjectSyntax body)
            {
                var dependsOnProperty = body.SafeGetPropertyByName(LanguageConstants.ResourceDependsOnPropertyName);

                if (dependsOnProperty?.Value is ArraySyntax declaredDependencies)
                {
                    if (model.GetSymbolInfo(declaringSyntax) is DeclaredSymbol thisResource)
                    {
                        // If this resource has no implicit dependencies, than all explicit dependsOn entries must be valid, so don't bother checking
                        if (inferredDependenciesMap.Value.TryGetValue(thisResource, out ImmutableHashSet <ResourceDependency>?inferredDependencies))
                        {
                            foreach (ArrayItemSyntax declaredDependency in declaredDependencies.Items)
                            {
                                // Is this a simple reference to a resource collection?
                                if (model.GetSymbolInfo(declaredDependency.Value) is ResourceSymbol referencedResource)
                                {
                                    if (referencedResource.IsCollection)
                                    {
                                        // Ignore dependsOn entries pointing to a resource collection - dependency analyis would
                                        // be complex and user probably knows what they're doing.
                                        continue;
                                    }

                                    if (inferredDependencies.Any(d => d.Resource == referencedResource))
                                    {
                                        this.diagnostics.Add(
                                            parent.CreateDiagnosticForSpan(
                                                declaredDependency.Span,
                                                referencedResource.Name));
                                    }
                                }
                            }
                        }
                    }
                }
            }