protected override Symbol MakePatternVariable(TypeSyntax type, SingleVariableDesignationSyntax designation, SyntaxNode nodeToBind)
 {
     return(designation == null ? null : GlobalExpressionVariable.Create(
                _containingType, _modifiers, type,
                designation.Identifier.ValueText, designation, designation.GetLocation(),
                _containingFieldOpt, nodeToBind));
 }
 protected override Symbol MakeDeclarationExpressionVariable(DeclarationExpressionSyntax node, SingleVariableDesignationSyntax designation, BaseArgumentListSyntax argumentListSyntaxOpt, SyntaxNode nodeToBind)
 {
     return(GlobalExpressionVariable.Create(
                _containingType, _modifiers, node.Type,
                designation.Identifier.ValueText, designation, designation.Identifier.GetLocation(),
                _containingFieldOpt, nodeToBind));
 }
Exemple #3
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));
 }
        /// <summary>
        /// In embedded statements, returns a BoundLocal when the type was explicit.
        /// In global statements, returns a BoundFieldAccess when the type was explicit.
        /// Otherwise returns a DeconstructionVariablePendingInference when the type is implicit.
        /// </summary>
        private BoundExpression BindDeconstructionVariable(
            TypeSymbol declType,
            TypeSyntax typeSyntax,
            SingleVariableDesignationSyntax designation,
            DiagnosticBag diagnostics)
        {
            SourceLocalSymbol localSymbol = LookupLocal(designation.Identifier);

            // is this a local?
            if ((object)localSymbol != null)
            {
                // Check for variable declaration errors.
                // Use the binder that owns the scope for the local because this (the current) binder
                // might own nested scope.
                var hasErrors = localSymbol.ScopeBinder.ValidateDeclarationNameConflictsInScope(localSymbol, diagnostics);

                if ((object)declType != null)
                {
                    CheckRestrictedTypeInAsync(this.ContainingMemberOrLambda, declType, diagnostics, typeSyntax);
                    return(new BoundLocal(designation, localSymbol, constantValueOpt: null, type: declType, hasErrors: hasErrors));
                }

                return(new DeconstructionVariablePendingInference(designation, localSymbol, receiverOpt: null));
            }

            // Is this a field?
            GlobalExpressionVariable field = LookupDeclaredField(designation);

            if ((object)field == null)
            {
                // We should have the right binder in the chain, cannot continue otherwise.
                throw ExceptionUtilities.Unreachable;
            }

            BoundThisReference receiver = ThisReference(designation, this.ContainingType, hasErrors: false,
                                                        wasCompilerGenerated: true);

            if ((object)declType != null)
            {
                TypeSymbol fieldType = field.GetFieldType(this.FieldsBeingBound);
                Debug.Assert(declType == fieldType);
                return(new BoundFieldAccess(designation,
                                            receiver,
                                            field,
                                            constantValueOpt: null,
                                            resultKind: LookupResultKind.Viable,
                                            type: fieldType));
            }

            return(new DeconstructionVariablePendingInference(designation, field, receiver));
        }
        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));
        }
 protected override Symbol MakeDeconstructionVariable(
     TypeSyntax closestTypeSyntax,
     SingleVariableDesignationSyntax designation,
     AssignmentExpressionSyntax deconstruction)
 {
     return(GlobalExpressionVariable.Create(
                containingType: _containingType,
                modifiers: DeclarationModifiers.Private,
                typeSyntax: closestTypeSyntax,
                name: designation.Identifier.ValueText,
                syntax: designation,
                location: designation.Location,
                containingFieldOpt: null,
                nodeToBind: deconstruction));
 }
Exemple #7
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));
            }
        }
        /// <summary>
        /// In embedded statements, returns a BoundLocal when the type was explicit.
        /// In global statements, returns a BoundFieldAccess when the type was explicit.
        /// Otherwise returns a DeconstructionVariablePendingInference when the type is implicit.
        /// </summary>
        private BoundExpression BindDeconstructionDeclarationVariable(
            TypeSyntax typeSyntax,
            SingleVariableDesignationSyntax designation,
            DiagnosticBag diagnostics)
        {
            SourceLocalSymbol localSymbol = LookupLocal(designation.Identifier);

            bool        hasErrors = false;
            bool        isVar;
            bool        isConst = false;
            AliasSymbol alias;
            TypeSymbol  declType = BindVariableType(designation, diagnostics, typeSyntax, ref isConst, out isVar, out alias);

            if (!isVar)
            {
                if (designation.Parent.Kind() == SyntaxKind.ParenthesizedVariableDesignation)
                {
                    // An explicit type can only be provided next to the variable
                    Error(diagnostics, ErrorCode.ERR_DeconstructionVarFormDisallowsSpecificType, designation);
                    hasErrors = true;
                }
            }

            // is this a local?
            if (localSymbol != null)
            {
                // Check for variable declaration errors.
                // Use the binder that owns the scope for the local because this (the current) binder
                // might own nested scope.
                hasErrors |= localSymbol.ScopeBinder.ValidateDeclarationNameConflictsInScope(localSymbol, diagnostics);

                if (!isVar)
                {
                    return(new BoundLocal(designation, localSymbol, constantValueOpt: null, type: declType, hasErrors: hasErrors));
                }

                return(new DeconstructionVariablePendingInference(designation, localSymbol, receiverOpt: null));
            }

            // Is this a field?
            GlobalExpressionVariable field = LookupDeclaredField(designation);

            if ((object)field == null)
            {
                // We should have the right binder in the chain, cannot continue otherwise.
                throw ExceptionUtilities.Unreachable;
            }

            BoundThisReference receiver = ThisReference(designation, this.ContainingType, hasErrors: false,
                                                        wasCompilerGenerated: true);

            if (!isVar)
            {
                TypeSymbol fieldType = field.GetFieldType(this.FieldsBeingBound);
                return(new BoundFieldAccess(designation,
                                            receiver,
                                            field,
                                            constantValueOpt: null,
                                            resultKind: LookupResultKind.Viable,
                                            type: fieldType,
                                            hasErrors: hasErrors));
            }

            return(new DeconstructionVariablePendingInference(designation, field, receiver));
        }
Exemple #9
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));
            }
        }