Exemple #1
0
        public override void VisitResourceAccessSyntax(ResourceAccessSyntax syntax)
        {
            base.VisitResourceAccessSyntax(syntax);

            // we need to resolve which resource delaration the LHS is pointing to - and then
            // validate that we can resolve the name.
            this.bindings.TryGetValue(syntax.BaseExpression, out var symbol);

            if (symbol is ErrorSymbol)
            {
                this.bindings.Add(syntax, symbol);
                return;
            }
            else if (symbol is null || symbol is not ResourceSymbol)
            {
                // symbol could be null in the case of an incomplete expression during parsing like `a:`
                var error = new ErrorSymbol(DiagnosticBuilder.ForPosition(syntax.ResourceName).ResourceRequiredForResourceAccess(symbol?.Kind.ToString() ?? LanguageConstants.ErrorName));
                this.bindings.Add(syntax, error);
                return;
            }

            // This is the symbol of LHS and it's a valid resource.
            var resourceSymbol = (ResourceSymbol)symbol;
            var resourceBody   = resourceSymbol.DeclaringResource.TryGetBody();

            if (resourceBody == null)
            {
                // If we have no body then there will be nothing to reference.
                var error = new ErrorSymbol(DiagnosticBuilder.ForPosition(syntax.ResourceName).NestedResourceNotFound(resourceSymbol.Name, syntax.ResourceName.IdentifierName, nestedResourceNames: new [] { "(none)", }));
                this.bindings.Add(syntax, error);
                return;
            }

            if (!this.allLocalScopes.TryGetValue(resourceBody, out var localScope))
            {
                // code defect in the declaration visitor
                throw new InvalidOperationException($"Local scope is missing for {syntax.GetType().Name} at {syntax.Span}");
            }

            var referencedResource = LookupResourceSymbolByName(localScope, syntax.ResourceName);

            if (referencedResource is null)
            {
                var nestedResourceNames = localScope.Declarations.OfType <ResourceSymbol>().Select(r => r.Name);
                var error = new ErrorSymbol(DiagnosticBuilder.ForPosition(syntax.ResourceName).NestedResourceNotFound(resourceSymbol.Name, syntax.ResourceName.IdentifierName, nestedResourceNames));
                this.bindings.Add(syntax, error);
                return;
            }

            // This is valid.
            this.bindings.Add(syntax, referencedResource);
        }
Exemple #2
0
 public virtual void VisitErrorSymbol(ErrorSymbol symbol)
 {
     VisitDescendants(symbol);
 }
Exemple #3
0
 public override void VisitErrorSymbol(ErrorSymbol symbol)
 {
     base.VisitErrorSymbol(symbol);
     this.CollectDiagnostics(symbol);
 }