Example #1
0
        public override Evaluation VisitDeclarationPattern(DeclarationPatternSyntax node)
        {
            node.Designation?.Accept <Evaluation>(this);
            node.Type?.Accept <Evaluation>(this);

            return(base.VisitDeclarationPattern(node));
        }
Example #2
0
 protected static void VerifyModelForDeclarationFieldDuplicate(
     SemanticModel model,
     DeclarationPatternSyntax decl,
     params IdentifierNameSyntax[] references)
 {
     VerifyModelForDeclarationField(model, decl, true, references);
 }
Example #3
0
        public override void VisitDeclarationPattern(DeclarationPatternSyntax node)
        {
            node.Designation?.Accept(this);
            node.Type?.Accept(this);

            base.VisitDeclarationPattern(node);
        }
Example #4
0
        public override void VisitDeclarationPattern(DeclarationPatternSyntax node)
        {
            if (node.Designation?.Kind() == SyntaxKind.SingleVariableDesignation)
            {
                TFieldOrLocalSymbol variable = MakePatternVariable(
                    node.Type,
                    (SingleVariableDesignationSyntax)node.Designation,
                    _nodeToBind
                    );
                if ((object)variable != null)
                {
                    _variablesBuilder.Add(variable);
                }
            }
            else
            {
                // The declaration pattern does not permit a ParenthesizedVariableDesignation
                Debug.Assert(
                    node.Designation == null ||
                    node.Designation.Kind() == SyntaxKind.DiscardDesignation
                    );
            }

            base.VisitDeclarationPattern(node);
        }
Example #5
0
 protected override Symbol MakePatternVariable(DeclarationPatternSyntax node, SyntaxNode nodeToBind)
 {
     return(GlobalExpressionVariable.Create(
                _containingType, _modifiers, node.Type,
                node.Identifier.ValueText, node, node.Identifier.GetLocation(),
                _containingFieldOpt, nodeToBind));
 }
Example #6
0
 private Doc PrintDeclarationPatternSyntax(DeclarationPatternSyntax node)
 {
     return(Concat(
                this.Print(node.Type),
                " ",
                this.Print(node.Designation)
                ));
 }
        public override void VisitDeclarationPattern(DeclarationPatternSyntax node)
        {
            var variable = MakePatternVariable(node, _nodeToBind);

            if ((object)variable != null)
            {
                _variablesBuilder.Add(variable);
            }

            base.VisitDeclarationPattern(node);
        }
 public override void VisitDeclarationPattern(DeclarationPatternSyntax node)
 {
     _localsBuilder.Add(SourceLocalSymbol.MakeLocalSymbolWithEnclosingContext(
                            _scopeBinder.ContainingMemberOrLambda,
                            scopeBinder: _scopeBinder,
                            nodeBinder: _enclosingBinder,
                            typeSyntax: node.Type,
                            identifierToken: node.Identifier,
                            kind: LocalDeclarationKind.PatternVariable,
                            nodeToBind: _nodeToBind,
                            forbiddenZone: null));
     base.VisitDeclarationPattern(node);
 }
Example #9
0
        public override void VisitDeclarationPattern(DeclarationPatternSyntax node)
        {
            if (!PreVisit(node))
            {
                return;
            }

            node.Designation?.Accept(this);
            node.Type?.Accept(this);

            base.VisitDeclarationPattern(node);

            PostVisit(node);
        }
        protected override Symbol MakePatternVariable(DeclarationPatternSyntax node, SyntaxNode nodeToBind)
        {
            var designation = node.Designation as SingleVariableDesignationSyntax;

            if (designation == null)
            {
                return(null);
            }

            return(GlobalExpressionVariable.Create(
                       _containingType, _modifiers, node.Type,
                       designation.Identifier.ValueText, designation, designation.GetLocation(),
                       _containingFieldOpt, nodeToBind));
        }
Example #11
0
        /// <summary>
        /// Try getting the <see cref="ILocalSymbol"/> for the node.
        /// Gets the semantic model for the tree if the node is not in the tree corresponding to <paramref name="semanticModel"/>.
        /// </summary>
        /// <param name="semanticModel">The <see cref="SemanticModel"/>.</param>
        /// <param name="node">The <see cref="DeclarationPatternSyntax"/>.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param>
        /// <param name="symbol">The symbol if found. Can be <see cref="IDiscardSymbol"/>.</param>
        /// <returns>True if a symbol was found.</returns>
        public static bool TryGetSymbol(this SemanticModel semanticModel, DeclarationPatternSyntax node, CancellationToken cancellationToken, [NotNullWhen(true)] out ISymbol?symbol)
        {
            if (semanticModel is null)
            {
                throw new ArgumentNullException(nameof(semanticModel));
            }

            if (node is null)
            {
                throw new ArgumentNullException(nameof(node));
            }

            symbol = GetDeclaredSymbolSafe(semanticModel, node, cancellationToken);
            return(symbol != null);
        }
Example #12
0
        protected static void VerifyModelNotSupported(
            SemanticModel model,
            DeclarationPatternSyntax decl,
            params IdentifierNameSyntax[] references)
        {
            Assert.Null(model.GetDeclaredSymbol(decl));
            var identifierText = decl.Identifier.ValueText;
            Assert.False(model.LookupSymbols(decl.SpanStart, name: identifierText).Any());

            Assert.False(model.LookupNames(decl.SpanStart).Contains(identifierText));
            Assert.Null(model.GetSymbolInfo(decl.Type).Symbol);

            Assert.Null(model.GetSymbolInfo(decl).Symbol);
            Assert.Null(model.GetTypeInfo(decl).Type);
            Assert.Null(model.GetDeclaredSymbol(decl));
            VerifyModelNotSupported(model, references);
        }
Example #13
0
        protected static void VerifyModelForDeclarationPattern(
            SemanticModel model,
            DeclarationPatternSyntax decl,
            bool isShadowed,
            params IdentifierNameSyntax[] references)
        {
            var symbol = model.GetDeclaredSymbol(decl);

            Assert.Equal(decl.Identifier.ValueText, symbol.Name);
            Assert.Equal(decl, symbol.DeclaringSyntaxReferences.Single().GetSyntax());
            Assert.Equal(LocalDeclarationKind.PatternVariable, ((LocalSymbol)symbol).DeclarationKind);
            Assert.Same(symbol, model.GetDeclaredSymbol((SyntaxNode)decl));

            if (isShadowed)
            {
                Assert.NotEqual(symbol, model.LookupSymbols(decl.SpanStart, name: decl.Identifier.ValueText).Single());
            }
            else
            {
                Assert.Same(symbol, model.LookupSymbols(decl.SpanStart, name: decl.Identifier.ValueText).Single());
            }

            Assert.True(model.LookupNames(decl.SpanStart).Contains(decl.Identifier.ValueText));

            Assert.True(SyntaxFacts.IsInNamespaceOrTypeContext(decl.Type));
            Assert.True(SyntaxFacts.IsInTypeOnlyContext(decl.Type));

            var local = ((SourceLocalSymbol)symbol);
            var type  = local.Type;

            if (type.IsErrorType())
            {
                Assert.Null(model.GetSymbolInfo(decl.Type).Symbol);
            }
            else
            {
                Assert.Equal(type, model.GetSymbolInfo(decl.Type).Symbol);
            }

            foreach (var reference in references)
            {
                Assert.Same(symbol, model.GetSymbolInfo(reference).Symbol);
                Assert.Same(symbol, model.LookupSymbols(reference.SpanStart, name: decl.Identifier.ValueText).Single());
                Assert.True(model.LookupNames(reference.SpanStart).Contains(decl.Identifier.ValueText));
            }
        }
Example #14
0
        protected static void VerifyModelForDeclarationPattern(
            SemanticModel model,
            DeclarationPatternSyntax decl,
            bool isShadowed,
            params IdentifierNameSyntax[] references)
        {
            var symbol = model.GetDeclaredSymbol(decl);
            Assert.Equal(decl.Identifier.ValueText, symbol.Name);
            Assert.Equal(decl, symbol.DeclaringSyntaxReferences.Single().GetSyntax());
            Assert.Equal(LocalDeclarationKind.PatternVariable, ((LocalSymbol)symbol).DeclarationKind);
            Assert.Same(symbol, model.GetDeclaredSymbol((SyntaxNode)decl));

            if (isShadowed)
            {
                Assert.NotEqual(symbol, model.LookupSymbols(decl.SpanStart, name: decl.Identifier.ValueText).Single());
            }
            else
            {
                Assert.Same(symbol, model.LookupSymbols(decl.SpanStart, name: decl.Identifier.ValueText).Single());
            }

            Assert.True(model.LookupNames(decl.SpanStart).Contains(decl.Identifier.ValueText));

            Assert.True(SyntaxFacts.IsInNamespaceOrTypeContext(decl.Type));
            Assert.True(SyntaxFacts.IsInTypeOnlyContext(decl.Type));

            var local = ((SourceLocalSymbol)symbol);
            var type = local.Type;
            if (type.IsErrorType())
            {
                Assert.Null(model.GetSymbolInfo(decl.Type).Symbol);
            }
            else
            {
                Assert.Equal(type, model.GetSymbolInfo(decl.Type).Symbol);
            }

            foreach (var reference in references)
            {
                Assert.Same(symbol, model.GetSymbolInfo(reference).Symbol);
                Assert.Same(symbol, model.LookupSymbols(reference.SpanStart, name: decl.Identifier.ValueText).Single());
                Assert.True(model.LookupNames(reference.SpanStart).Contains(decl.Identifier.ValueText));
            }
        }
Example #15
0
        protected static void VerifyModelForDeclarationField(
            SemanticModel model,
            SingleVariableDesignationSyntax designation,
            bool duplicate,
            params IdentifierNameSyntax[] references)
        {
            var symbol = model.GetDeclaredSymbol(designation);

            Assert.Equal(designation.Identifier.ValueText, symbol.Name);
            Assert.Equal(SymbolKind.Field, symbol.Kind);
            Assert.Equal(designation, symbol.DeclaringSyntaxReferences.Single().GetSyntax());
            Assert.Same(symbol, model.GetDeclaredSymbol((SyntaxNode)designation));

            var symbols = model.LookupSymbols(designation.SpanStart, name: designation.Identifier.ValueText);
            var names   = model.LookupNames(designation.SpanStart);

            if (duplicate)
            {
                Assert.True(symbols.Count() > 1);
                Assert.Contains(symbol, symbols);
            }
            else
            {
                Assert.Same(symbol, symbols.Single());
            }

            Assert.Contains(designation.Identifier.ValueText, names);

            DeclarationPatternSyntax decl = (DeclarationPatternSyntax)designation.Parent;
            var local      = (FieldSymbol)symbol;
            var typeSyntax = decl.Type;

            Assert.True(SyntaxFacts.IsInNamespaceOrTypeContext(typeSyntax));
            Assert.True(SyntaxFacts.IsInTypeOnlyContext(typeSyntax));

            if (typeSyntax.IsVar && local.Type.IsErrorType())
            {
                Assert.Null(model.GetSymbolInfo(typeSyntax).Symbol);
            }
            else
            {
                Assert.Equal(local.Type, model.GetSymbolInfo(typeSyntax).Symbol);
            }

            var declarator = designation.Ancestors().OfType <VariableDeclaratorSyntax>().FirstOrDefault();
            var inFieldDeclaratorArgumentlist = declarator != null && declarator.Parent.Parent.Kind() != SyntaxKind.LocalDeclarationStatement &&
                                                (declarator.ArgumentList?.Contains(designation)).GetValueOrDefault();

            // this is a declaration site, not a use site.
            Assert.Null(model.GetSymbolInfo(designation).Symbol);
            Assert.Null(model.GetSymbolInfo(designation).Symbol);

            foreach (var reference in references)
            {
                var referenceInfo = model.GetSymbolInfo(reference);
                symbols = model.LookupSymbols(reference.SpanStart, name: designation.Identifier.ValueText);

                if (duplicate)
                {
                    Assert.Null(referenceInfo.Symbol);
                    Assert.Contains(symbol, referenceInfo.CandidateSymbols);
                    Assert.True(symbols.Count() > 1);
                    Assert.Contains(symbol, symbols);
                }
                else
                {
                    Assert.Same(symbol, referenceInfo.Symbol);
                    Assert.Same(symbol, symbols.Single());
                    Assert.Equal(local.Type, model.GetTypeInfo(reference).Type);
                }

                Assert.True(model.LookupNames(reference.SpanStart).Contains(designation.Identifier.ValueText));
            }

            if (!inFieldDeclaratorArgumentlist)
            {
                var dataFlowParent = designation.FirstAncestorOrSelf <ExpressionSyntax>();

                if (model.IsSpeculativeSemanticModel)
                {
                    Assert.Throws <NotSupportedException>(() => model.AnalyzeDataFlow(dataFlowParent));
                }
                else
                {
                    var dataFlow = model.AnalyzeDataFlow(dataFlowParent);

                    if (dataFlow.Succeeded)
                    {
                        Assert.False(dataFlow.VariablesDeclared.Contains(symbol, ReferenceEqualityComparer.Instance));
                        Assert.False(dataFlow.AlwaysAssigned.Contains(symbol, ReferenceEqualityComparer.Instance));
                        Assert.False(dataFlow.WrittenInside.Contains(symbol, ReferenceEqualityComparer.Instance));
                        Assert.False(dataFlow.DataFlowsIn.Contains(symbol, ReferenceEqualityComparer.Instance));
                        Assert.False(dataFlow.ReadInside.Contains(symbol, ReferenceEqualityComparer.Instance));
                        Assert.False(dataFlow.DataFlowsOut.Contains(symbol, ReferenceEqualityComparer.Instance));
                        Assert.False(dataFlow.ReadOutside.Contains(symbol, ReferenceEqualityComparer.Instance));
                        Assert.False(dataFlow.WrittenOutside.Contains(symbol, ReferenceEqualityComparer.Instance));
                    }
                }
            }
        }
 public override void VisitDeclarationPattern(DeclarationPatternSyntax node)
 {
     VisitType(node.Type);
     //base.VisitDeclarationPattern(node);
 }
Example #17
0
        private static void VerifyModelForDeclarationPattern(SemanticModel model, DeclarationPatternSyntax decl, params IdentifierNameSyntax[] references)
        {
            var symbol = model.GetDeclaredSymbol(decl);
            Assert.Equal(decl.Identifier.ValueText, symbol.Name);
            Assert.Equal(LocalDeclarationKind.PatternVariable, ((LocalSymbol)symbol).DeclarationKind);
            Assert.Same(symbol, model.GetDeclaredSymbol((SyntaxNode)decl));
            Assert.Same(symbol, model.LookupSymbols(decl.SpanStart, name: decl.Identifier.ValueText).Single());
            Assert.True(model.LookupNames(decl.SpanStart).Contains(decl.Identifier.ValueText));

            foreach (var reference in references)
            {
                Assert.Same(symbol, model.GetSymbolInfo(reference).Symbol);
                Assert.Same(symbol, model.LookupSymbols(reference.SpanStart, name: decl.Identifier.ValueText).Single());
                Assert.True(model.LookupNames(reference.SpanStart).Contains(decl.Identifier.ValueText));
            }
        }
Example #18
0
        private BoundPattern BindDeclarationPattern(
            DeclarationPatternSyntax node,
            BoundExpression operand,
            TypeSymbol operandType,
            bool hasErrors,
            DiagnosticBag diagnostics)
        {
            Debug.Assert(operand != null && operandType != (object)null);

            var typeSyntax = node.Type;

            bool isVar;
            AliasSymbol aliasOpt;
            TypeSymbol declType = BindType(typeSyntax, diagnostics, out isVar, out aliasOpt);
            if (isVar)
            {
                declType = operandType;
            }

            if (declType == (object)null)
            {
                Debug.Assert(hasErrors);
                declType = this.CreateErrorType("var");
            }

            var boundDeclType = new BoundTypeExpression(typeSyntax, aliasOpt, inferredType: isVar, type: declType);
            if (IsOperatorErrors(node, operandType, boundDeclType, diagnostics))
            {
                hasErrors = true;
            }
            else
            {
                hasErrors |= CheckValidPatternType(typeSyntax, operand, operandType, declType,
                                                   isVar: isVar, patternTypeWasInSource: true, diagnostics: diagnostics);
            }

            switch (node.Designation.Kind())
            {
                case SyntaxKind.SingleVariableDesignation:
                    break;
                case SyntaxKind.DiscardedDesignation:
                    return new BoundDeclarationPattern(node, null, boundDeclType, isVar, hasErrors);
                default:
                    throw ExceptionUtilities.UnexpectedValue(node.Designation.Kind());
            }

            var designation = (SingleVariableDesignationSyntax)node.Designation;
            var identifier = designation.Identifier;
            SourceLocalSymbol localSymbol = this.LookupLocal(identifier);

            if (localSymbol != (object)null)
            {
                if (InConstructorInitializer || InFieldInitializer)
                {
                    Error(diagnostics, ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, node);
                }

                localSymbol.SetType(declType);

                // Check for variable declaration errors.
                hasErrors |= localSymbol.ScopeBinder.ValidateDeclarationNameConflictsInScope(localSymbol, diagnostics);

                if (!hasErrors)
                {
                    hasErrors = CheckRestrictedTypeInAsync(this.ContainingMemberOrLambda, declType, diagnostics, typeSyntax);
                }

                return new BoundDeclarationPattern(node, localSymbol, boundDeclType, isVar, hasErrors);
            }
            else
            {
                // We should have the right binder in the chain for a script or interactive, so we use the field for the pattern.
                Debug.Assert(node.SyntaxTree.Options.Kind != SourceCodeKind.Regular);
                GlobalExpressionVariable expressionVariableField = LookupDeclaredField(designation);
                DiagnosticBag tempDiagnostics = DiagnosticBag.GetInstance();
                expressionVariableField.SetType(declType, tempDiagnostics);
                tempDiagnostics.Free();
                BoundExpression receiver = SynthesizeReceiver(node, expressionVariableField, diagnostics);
                var variableAccess = new BoundFieldAccess(node, receiver, expressionVariableField, null, hasErrors);
                return new BoundDeclarationPattern(node, expressionVariableField, variableAccess, boundDeclType, isVar, hasErrors);
            }
        }
Example #19
0
 public override void VisitDeclarationPattern(DeclarationPatternSyntax node)
 {
     Log(node, "Unsupported Syntax !");
 }
Example #20
0
        private BoundPattern BindDeclarationPattern(
            DeclarationPatternSyntax node,
            TypeSymbol operandType,
            bool hasErrors,
            DiagnosticBag diagnostics)
        {
            Debug.Assert(operandType != (object)null);

            var typeSyntax = node.Type;

            bool        isVar;
            AliasSymbol aliasOpt;
            TypeSymbol  declType = BindTypeOrVarKeyword(typeSyntax, diagnostics, out isVar, out aliasOpt);

            if (isVar)
            {
                declType = operandType;
            }

            if (declType == (object)null)
            {
                Debug.Assert(hasErrors);
                declType = this.CreateErrorType("var");
            }

            var boundDeclType = new BoundTypeExpression(typeSyntax, aliasOpt, inferredType: isVar, type: declType);

            if (IsOperatorErrors(node, operandType, boundDeclType, diagnostics))
            {
                hasErrors = true;
            }
            else
            {
                hasErrors |= CheckValidPatternType(typeSyntax, operandType, declType,
                                                   isVar: isVar, patternTypeWasInSource: true, diagnostics: diagnostics);
            }

            switch (node.Designation.Kind())
            {
            case SyntaxKind.SingleVariableDesignation:
                break;

            case SyntaxKind.DiscardDesignation:
                return(new BoundDeclarationPattern(node, null, boundDeclType, isVar, hasErrors));

            default:
                throw ExceptionUtilities.UnexpectedValue(node.Designation.Kind());
            }

            var designation = (SingleVariableDesignationSyntax)node.Designation;
            var identifier  = designation.Identifier;
            SourceLocalSymbol localSymbol = this.LookupLocal(identifier);

            if (localSymbol != (object)null)
            {
                if ((InConstructorInitializer || InFieldInitializer) && ContainingMemberOrLambda.ContainingSymbol.Kind == SymbolKind.NamedType)
                {
                    CheckFeatureAvailability(node, MessageID.IDS_FeatureExpressionVariablesInQueriesAndInitializers, diagnostics);
                }

                localSymbol.SetType(declType);

                // Check for variable declaration errors.
                hasErrors |= localSymbol.ScopeBinder.ValidateDeclarationNameConflictsInScope(localSymbol, diagnostics);

                if (!hasErrors)
                {
                    hasErrors = CheckRestrictedTypeInAsync(this.ContainingMemberOrLambda, declType, diagnostics, typeSyntax);
                }

                return(new BoundDeclarationPattern(node, localSymbol, boundDeclType, isVar, hasErrors));
            }
            else
            {
                // We should have the right binder in the chain for a script or interactive, so we use the field for the pattern.
                Debug.Assert(node.SyntaxTree.Options.Kind != SourceCodeKind.Regular);
                GlobalExpressionVariable expressionVariableField = LookupDeclaredField(designation);
                DiagnosticBag            tempDiagnostics         = DiagnosticBag.GetInstance();
                expressionVariableField.SetType(declType, tempDiagnostics);
                tempDiagnostics.Free();
                BoundExpression receiver       = SynthesizeReceiver(node, expressionVariableField, diagnostics);
                var             variableAccess = new BoundFieldAccess(node, receiver, expressionVariableField, null, hasErrors);
                return(new BoundDeclarationPattern(node, expressionVariableField, variableAccess, boundDeclType, isVar, hasErrors));
            }
        }
        internal static async Task ComputeRefactoringAsync(RefactoringContext context, DeclarationPatternSyntax declarationPattern)
        {
            if (context.IsRefactoringEnabled(RefactoringIdentifiers.RenameIdentifierAccordingToTypeName))
            {
                VariableDesignationSyntax designation = declarationPattern.Designation;

                if (designation?.IsKind(SyntaxKind.SingleVariableDesignation) == true)
                {
                    var singleVariableDesignation = (SingleVariableDesignationSyntax)designation;

                    SyntaxToken identifier = singleVariableDesignation.Identifier;

                    if (identifier.Span.Contains(context.Span))
                    {
                        SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                        ISymbol symbol = semanticModel.GetDeclaredSymbol(singleVariableDesignation, context.CancellationToken);

                        if (symbol?.IsLocal() == true)
                        {
                            var localSymbol = (ILocalSymbol)symbol;

                            string oldName = identifier.ValueText;

                            string newName = NameGenerator.Default.CreateUniqueLocalName(
                                localSymbol.Type,
                                oldName,
                                semanticModel,
                                singleVariableDesignation.SpanStart,
                                cancellationToken: context.CancellationToken);

                            if (newName != null)
                            {
                                context.RegisterRefactoring(
                                    $"Rename '{oldName}' to '{newName}'",
                                    cancellationToken => Renamer.RenameSymbolAsync(context.Solution, symbol, newName, default(OptionSet), cancellationToken));
                            }
                        }
                    }
                }
            }
        }
Example #22
0
        private static void VerifyModelForDeclarationPattern(SemanticModel model, DeclarationPatternSyntax decl, bool isShadowed, params IdentifierNameSyntax[] references)
        {
            var symbol = model.GetDeclaredSymbol(decl);
            Assert.Equal(decl.Identifier.ValueText, symbol.Name);
            Assert.Equal(LocalDeclarationKind.PatternVariable, ((LocalSymbol)symbol).DeclarationKind);
            Assert.Same(symbol, model.GetDeclaredSymbol((SyntaxNode)decl));

            if (isShadowed)
            {
                Assert.NotEqual(symbol, model.LookupSymbols(decl.SpanStart, name: decl.Identifier.ValueText).Single());
            }
            else
            {
                Assert.Same(symbol, model.LookupSymbols(decl.SpanStart, name: decl.Identifier.ValueText).Single());
            }

            Assert.True(model.LookupNames(decl.SpanStart).Contains(decl.Identifier.ValueText));

            var type = ((LocalSymbol)symbol).Type;
            if (!decl.Type.IsVar || !type.IsErrorType())
            {
                Assert.Equal(type, model.GetSymbolInfo(decl.Type).Symbol);
            }

            foreach (var reference in references)
            {
                Assert.Same(symbol, model.GetSymbolInfo(reference).Symbol);
                Assert.Same(symbol, model.LookupSymbols(reference.SpanStart, name: decl.Identifier.ValueText).Single());
                Assert.True(model.LookupNames(reference.SpanStart).Contains(decl.Identifier.ValueText));
            }
        }
 public static Doc Print(DeclarationPatternSyntax node)
 {
     return(Doc.Concat(Node.Print(node.Type), " ", Node.Print(node.Designation)));
 }
 /// <inheritdoc />
 public override Expression VisitDeclarationPattern(DeclarationPatternSyntax node)
 {
     throw Unexpected(node, nameof(VisitIsPatternExpression));
 }
Example #25
0
        private BoundPattern BindDeclarationPattern(
            DeclarationPatternSyntax node,
            BoundExpression operand,
            TypeSymbol operandType,
            bool hasErrors,
            DiagnosticBag diagnostics)
        {
            Debug.Assert(operand != null && operandType != (object)null);

            var typeSyntax = node.Type;
            var identifier = node.Identifier;

            bool        isVar;
            AliasSymbol aliasOpt;
            TypeSymbol  declType = BindType(typeSyntax, diagnostics, out isVar, out aliasOpt);

            if (isVar)
            {
                declType = operandType;
            }

            if (declType == (object)null)
            {
                Debug.Assert(hasErrors);
                declType = this.CreateErrorType("var");
            }

            var boundDeclType = new BoundTypeExpression(typeSyntax, aliasOpt, inferredType: isVar, type: declType);

            if (IsOperatorErrors(node, operandType, boundDeclType, diagnostics))
            {
                hasErrors = true;
            }
            else
            {
                hasErrors |= CheckValidPatternType(typeSyntax, operand, operandType, declType,
                                                   isVar: isVar, patternTypeWasInSource: true, diagnostics: diagnostics);
            }

            SourceLocalSymbol localSymbol = this.LookupLocal(identifier);

            if (localSymbol != (object)null)
            {
                if (InConstructorInitializer || InFieldInitializer)
                {
                    Error(diagnostics, ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, node);
                }

                localSymbol.SetType(declType);

                // Check for variable declaration errors.
                hasErrors |= localSymbol.ScopeBinder.ValidateDeclarationNameConflictsInScope(localSymbol, diagnostics);

                if (!hasErrors)
                {
                    hasErrors = CheckRestrictedTypeInAsync(this.ContainingMemberOrLambda, declType, diagnostics, typeSyntax);
                }

                return(new BoundDeclarationPattern(node, localSymbol, boundDeclType, isVar, hasErrors));
            }
            else
            {
                // We should have the right binder in the chain for a script or interactive, so we use the field for the pattern.
                Debug.Assert(node.SyntaxTree.Options.Kind != SourceCodeKind.Regular);
                GlobalExpressionVariable expressionVariableField = LookupDeclaredField(node);
                DiagnosticBag            tempDiagnostics         = DiagnosticBag.GetInstance();
                expressionVariableField.SetType(declType, tempDiagnostics);
                tempDiagnostics.Free();
                BoundExpression receiver       = SynthesizeReceiver(node, expressionVariableField, diagnostics);
                var             variableAccess = new BoundFieldAccess(node, receiver, expressionVariableField, null, hasErrors);
                return(new BoundDeclarationPattern(node, expressionVariableField, variableAccess, boundDeclType, isVar, hasErrors));
            }
        }
 public override void VisitDeclarationPattern(DeclarationPatternSyntax node)
 {
 }
 protected abstract TFieldOrLocalSymbol MakePatternVariable(DeclarationPatternSyntax node, SyntaxNode nodeToBind);
Example #28
0
        private BoundPattern BindDeclarationPattern(
            DeclarationPatternSyntax node,
            BoundExpression operand,
            TypeSymbol operandType,
            bool hasErrors,
            DiagnosticBag diagnostics)
        {
            Debug.Assert(operand != null || operandType != (object)null);

            if (InConstructorInitializer || InFieldInitializer)
            {
                Error(diagnostics, ErrorCode.ERR_ExpressionVariableInConstructorOrFieldInitializer, node);
            }

            var typeSyntax = node.Type;
            var identifier = node.Identifier;

            bool        isVar;
            AliasSymbol aliasOpt;
            TypeSymbol  declType = BindType(typeSyntax, diagnostics, out isVar, out aliasOpt);

            if (isVar && operandType != (object)null)
            {
                declType = operandType;
            }

            if (declType == (object)null)
            {
                Debug.Assert(hasErrors);
                declType = this.CreateErrorType("var");
            }

            var boundDeclType = new BoundTypeExpression(typeSyntax, aliasOpt, inferredType: isVar, type: declType);

            if (IsOperatorErrors(node, operandType, boundDeclType, diagnostics))
            {
                hasErrors = true;
            }
            else
            {
                hasErrors |= CheckValidPatternType(typeSyntax, operand, operandType, declType,
                                                   isVar: isVar, patternTypeWasInSource: true, diagnostics: diagnostics);
            }

            SourceLocalSymbol localSymbol = this.LookupLocal(identifier);

            // In error scenarios with misplaced code, it is possible we can't bind the local declaration.
            // This occurs through the semantic model.  In that case concoct a plausible result.
            if (localSymbol == (object)null)
            {
                localSymbol = SourceLocalSymbol.MakeLocal(
                    ContainingMemberOrLambda,
                    this,
                    false, // do not allow ref
                    typeSyntax,
                    identifier,
                    LocalDeclarationKind.PatternVariable);
            }

            localSymbol.SetType(declType);

            // Check for variable declaration errors.
            hasErrors |= localSymbol.ScopeBinder.ValidateDeclarationNameConflictsInScope(localSymbol, diagnostics);

            if (this.ContainingMemberOrLambda.Kind == SymbolKind.Method &&
                ((MethodSymbol)this.ContainingMemberOrLambda).IsAsync &&
                declType.IsRestrictedType() &&
                !hasErrors)
            {
                Error(diagnostics, ErrorCode.ERR_BadSpecialByRefLocal, typeSyntax, declType);
                hasErrors = true;
            }

            return(new BoundDeclarationPattern(node, localSymbol, boundDeclType, isVar, hasErrors));
        }
Example #29
0
 public override void VisitDeclarationPattern(DeclarationPatternSyntax node)
 {
     throw new NotImplementedException();
 }
 /// <summary>
 /// Given a declaration pattern syntax, get the corresponding symbol.
 /// </summary>
 /// <param name="declarationSyntax">The syntax node that declares a variable.</param>
 /// <param name="cancellationToken">The cancellation token.</param>
 /// <returns>The symbol that was declared.</returns>
 public override ILocalSymbol GetDeclaredSymbol(DeclarationPatternSyntax declarationSyntax, CancellationToken cancellationToken = default(CancellationToken))
 {
     var memberModel = this.GetMemberModel(declarationSyntax);
     return memberModel == null ? null : memberModel.GetDeclaredSymbol(declarationSyntax, cancellationToken);
 }
 public override void VisitDeclarationPattern(DeclarationPatternSyntax node)
 {
     _localsBuilder.Add(SourceLocalSymbol.MakeLocalSymbolWithEnclosingContext(
         _scopeBinder.ContainingMemberOrLambda,
         scopeBinder: _scopeBinder,
         nodeBinder: _enclosingBinder,
         typeSyntax: node.Type,
         identifierToken: node.Identifier,
         kind: LocalDeclarationKind.PatternVariable,
         nodeToBind: _nodeToBind,
         forbiddenZone: null));
     base.VisitDeclarationPattern(node);
 }
Example #32
0
 /// <summary>
 /// Given a declaration pattern syntax, get the corresponding symbol.
 /// </summary>
 /// <param name="declarationSyntax">The syntax node that declares a variable.</param>
 /// <param name="cancellationToken">The cancellation token.</param>
 /// <returns>The symbol that was declared.</returns>
 public abstract ISymbol GetDeclaredSymbol(DeclarationPatternSyntax declarationSyntax, CancellationToken cancellationToken = default(CancellationToken));
Example #33
0
 public override void VisitDeclarationPattern(DeclarationPatternSyntax node)
 {
     _declarationPatterns.Add(SourceLocalSymbol.MakeLocal(_binder.ContainingMemberOrLambda, _binder, RefKind.None, node.Type, node.Identifier, LocalDeclarationKind.PatternVariable));
     base.VisitDeclarationPattern(node);
 }
Example #34
0
 public override ISymbol GetDeclaredSymbol(DeclarationPatternSyntax declarationSyntax, CancellationToken cancellationToken = default(CancellationToken))
 {
     CheckSyntaxNode(declarationSyntax);
     return GetDeclaredLocal(declarationSyntax, declarationSyntax.Identifier);
 }
Example #35
0
 protected static void AssertContainedInDeclaratorArguments(DeclarationPatternSyntax decl)
 {
     Assert.True(decl.Ancestors().OfType<VariableDeclaratorSyntax>().First().ArgumentList.Contains(decl));
 }
Example #36
0
 public override void VisitDeclarationPattern(DeclarationPatternSyntax node)
 {
     _localsBuilder.Add(SourceLocalSymbol.MakeLocal(_binder.ContainingMemberOrLambda, _binder, RefKind.None, node.Type, node.Identifier, LocalDeclarationKind.PatternVariable));
     base.VisitDeclarationPattern(node);
 }
Example #37
0
 protected static void VerifyModelForDeclarationPattern(SemanticModel model, DeclarationPatternSyntax decl, params IdentifierNameSyntax[] references)
 {
     VerifyModelForDeclarationPattern(model, decl, false, references);
 }
Example #38
0
 private static void VerifyModelForDeclarationPatternDuplicateInSameScope(SemanticModel model, DeclarationPatternSyntax decl)
 {
     var symbol = model.GetDeclaredSymbol(decl);
     Assert.Equal(decl.Identifier.ValueText, symbol.Name);
     Assert.Equal(LocalDeclarationKind.PatternVariable, ((LocalSymbol)symbol).DeclarationKind);
     Assert.Same(symbol, model.GetDeclaredSymbol((SyntaxNode)decl));
     Assert.NotEqual(symbol, model.LookupSymbols(decl.SpanStart, name: decl.Identifier.ValueText).Single());
     Assert.True(model.LookupNames(decl.SpanStart).Contains(decl.Identifier.ValueText));
 }
Example #39
0
        protected static void VerifyModelForDeclarationPatternDuplicateInSameScope(SemanticModel model, DeclarationPatternSyntax decl)
        {
            var symbol = model.GetDeclaredSymbol(decl);
            Assert.Equal(decl.Identifier.ValueText, symbol.Name);
            Assert.Equal(decl, symbol.DeclaringSyntaxReferences.Single().GetSyntax());
            Assert.Equal(LocalDeclarationKind.PatternVariable, ((LocalSymbol)symbol).DeclarationKind);
            Assert.Same(symbol, model.GetDeclaredSymbol((SyntaxNode)decl));
            Assert.NotEqual(symbol, model.LookupSymbols(decl.SpanStart, name: decl.Identifier.ValueText).Single());
            Assert.True(model.LookupNames(decl.SpanStart).Contains(decl.Identifier.ValueText));

            var type = ((LocalSymbol)symbol).Type;
            if (!decl.Type.IsVar || !type.IsErrorType())
            {
                Assert.Equal(type, model.GetSymbolInfo(decl.Type).Symbol);
            }
        }
Example #40
0
        private BoundPattern BindDeclarationPattern(
            DeclarationPatternSyntax node,
            BoundExpression operand,
            TypeSymbol operandType,
            bool hasErrors,
            DiagnosticBag diagnostics)
        {
            Debug.Assert(operand != null || operandType != (object)null);
            var typeSyntax = node.Type;
            var identifier = node.Identifier;

            bool isVar;
            AliasSymbol aliasOpt;
            TypeSymbol declType = BindType(typeSyntax, diagnostics, out isVar, out aliasOpt);
            if (isVar && operandType != (object)null)
            {
                declType = operandType;
            }

            if (declType == (object)null)
            {
                Debug.Assert(hasErrors);
                declType = this.CreateErrorType();
            }

            var boundDeclType = new BoundTypeExpression(typeSyntax, aliasOpt, inferredType: isVar, type: declType);
            if (IsOperatorErrors(node, operandType, boundDeclType, diagnostics))
            {
                hasErrors = true;
            }
            else
            {
                hasErrors |= CheckValidPatternType(typeSyntax, operand, operandType, declType,
                                                  isVar: isVar, patternTypeWasInSource: true, diagnostics: diagnostics);
            }

            SourceLocalSymbol localSymbol = this.LookupLocal(identifier);

            // In error scenarios with misplaced code, it is possible we can't bind the local declaration.
            // This occurs through the semantic model.  In that case concoct a plausible result.
            if (localSymbol == (object)null)
            {
                localSymbol = SourceLocalSymbol.MakeLocal(
                    ContainingMemberOrLambda,
                    this,
                    RefKind.None,
                    typeSyntax,
                    identifier,
                    LocalDeclarationKind.PatternVariable);
            }

            if (isVar)
            {
                localSymbol.SetTypeSymbol(operandType);
            }

            // Check for variable declaration errors.
            hasErrors |= this.ValidateDeclarationNameConflictsInScope(localSymbol, diagnostics);

            if (this.ContainingMemberOrLambda.Kind == SymbolKind.Method
                && ((MethodSymbol)this.ContainingMemberOrLambda).IsAsync
                && declType.IsRestrictedType()
                && !hasErrors)
            {
                Error(diagnostics, ErrorCode.ERR_BadSpecialByRefLocal, typeSyntax, declType);
                hasErrors = true;
            }

            DeclareLocalVariable(localSymbol, identifier, declType);
            return new BoundDeclarationPattern(node, localSymbol, boundDeclType, isVar, hasErrors);
        }
Example #41
0
 /// <summary>
 /// Given a declaration pattern syntax, get the corresponding symbol.
 /// </summary>
 /// <param name="declarationSyntax">The syntax node that declares a variable.</param>
 /// <param name="cancellationToken">The cancellation token.</param>
 /// <returns>The symbol that was declared.</returns>
 public override ISymbol GetDeclaredSymbol(DeclarationPatternSyntax declarationSyntax, CancellationToken cancellationToken = default(CancellationToken))
 {
     var memberModel = this.GetMemberModel(declarationSyntax);
     return memberModel?.GetDeclaredSymbol(declarationSyntax, cancellationToken) ??
         GetEnclosingBinder(declarationSyntax.Position)?.LookupDeclaredField(declarationSyntax);
 }
Example #42
0
        private static void VerifyModelNotSupported(SemanticModel model, DeclarationPatternSyntax decl, params IdentifierNameSyntax[] references)
        {
            Assert.Null(model.GetDeclaredSymbol(decl));
            Assert.Null(model.GetDeclaredSymbol((SyntaxNode)decl));

            Assert.False(model.LookupSymbols(decl.SpanStart, name: decl.Identifier.ValueText).Any());
            Assert.False(model.LookupNames(decl.SpanStart).Contains(decl.Identifier.ValueText));

            Assert.Null(model.GetSymbolInfo(decl.Type).Symbol);

            foreach (var reference in references)
            {
                Assert.Null(model.GetSymbolInfo(reference).Symbol);
                Assert.False(model.LookupSymbols(reference.SpanStart, name: decl.Identifier.ValueText).Any());
                Assert.False(model.LookupNames(reference.SpanStart).Contains(decl.Identifier.ValueText));
            }
        }
 public override void VisitDeclarationPattern(DeclarationPatternSyntax node)
 {
     _localsBuilder.Add(SourceLocalSymbol.MakeLocal(_scopeBinder.ContainingMemberOrLambda, _scopeBinder, false, node.Type, node.Identifier, LocalDeclarationKind.PatternVariable));
     base.VisitDeclarationPattern(node);
 }
        protected static void VerifyModelForDeclarationField(
            SemanticModel model,
            DeclarationPatternSyntax decl,
            bool duplicate,
            params IdentifierNameSyntax[] references)
        {
            var symbol = model.GetDeclaredSymbol(decl);
            Assert.Equal(decl.Identifier.ValueText, symbol.Name);
            Assert.Equal(SymbolKind.Field, symbol.Kind);
            Assert.Equal(decl, symbol.DeclaringSyntaxReferences.Single().GetSyntax());
            Assert.Same(symbol, model.GetDeclaredSymbol((SyntaxNode)decl));

            var symbols = model.LookupSymbols(decl.SpanStart, name: decl.Identifier.ValueText);
            var names = model.LookupNames(decl.SpanStart);

            if (duplicate)
            {
                Assert.True(symbols.Count() > 1);
                Assert.Contains(symbol, symbols);
            }
            else
            {
                Assert.Same(symbol, symbols.Single());
            }

            Assert.Contains(decl.Identifier.ValueText, names);

            var local = (FieldSymbol)symbol;
            var typeSyntax = decl.Type;

            Assert.True(SyntaxFacts.IsInNamespaceOrTypeContext(typeSyntax));
            Assert.True(SyntaxFacts.IsInTypeOnlyContext(typeSyntax));

            if (typeSyntax.IsVar && local.Type.IsErrorType())
            {
                Assert.Null(model.GetSymbolInfo(typeSyntax).Symbol);
            }
            else
            {
                Assert.Equal(local.Type, model.GetSymbolInfo(typeSyntax).Symbol);
            }

            var declarator = decl.Ancestors().OfType<VariableDeclaratorSyntax>().FirstOrDefault();
            var inFieldDeclaratorArgumentlist = declarator != null && declarator.Parent.Parent.Kind() != SyntaxKind.LocalDeclarationStatement &&
                                           (declarator.ArgumentList?.Contains(decl)).GetValueOrDefault();

            // this is a declaration site, not a use site.
            Assert.Null(model.GetSymbolInfo(decl).Symbol);
            Assert.Null(model.GetSymbolInfo(decl).Symbol);

            foreach (var reference in references)
            {
                var referenceInfo = model.GetSymbolInfo(reference);
                symbols = model.LookupSymbols(reference.SpanStart, name: decl.Identifier.ValueText);

                if (duplicate)
                {
                    Assert.Null(referenceInfo.Symbol);
                    Assert.Contains(symbol, referenceInfo.CandidateSymbols);
                    Assert.True(symbols.Count() > 1);
                    Assert.Contains(symbol, symbols);
                }
                else
                {
                    Assert.Same(symbol, referenceInfo.Symbol);
                    Assert.Same(symbol, symbols.Single());
                    Assert.Equal(local.Type, model.GetTypeInfo(reference).Type);
                }

                Assert.True(model.LookupNames(reference.SpanStart).Contains(decl.Identifier.ValueText));
            }

            if (!inFieldDeclaratorArgumentlist)
            {
                var dataFlowParent = decl.FirstAncestorOrSelf<ExpressionSyntax>();

                if (model.IsSpeculativeSemanticModel)
                {
                    Assert.Throws<NotSupportedException>(() => model.AnalyzeDataFlow(dataFlowParent));
                }
                else
                {
                    var dataFlow = model.AnalyzeDataFlow(dataFlowParent);

                    if (dataFlow.Succeeded)
                    {
                        Assert.False(dataFlow.VariablesDeclared.Contains(symbol, ReferenceEqualityComparer.Instance));
                        Assert.False(dataFlow.AlwaysAssigned.Contains(symbol, ReferenceEqualityComparer.Instance));
                        Assert.False(dataFlow.WrittenInside.Contains(symbol, ReferenceEqualityComparer.Instance));
                        Assert.False(dataFlow.DataFlowsIn.Contains(symbol, ReferenceEqualityComparer.Instance));
                        Assert.False(dataFlow.ReadInside.Contains(symbol, ReferenceEqualityComparer.Instance));
                        Assert.False(dataFlow.DataFlowsOut.Contains(symbol, ReferenceEqualityComparer.Instance));
                        Assert.False(dataFlow.ReadOutside.Contains(symbol, ReferenceEqualityComparer.Instance));
                        Assert.False(dataFlow.WrittenOutside.Contains(symbol, ReferenceEqualityComparer.Instance));
                    }
                }
            }
        }
Example #45
0
 public override void VisitDeclarationPattern(DeclarationPatternSyntax node) => base.VisitDeclarationPattern(node);