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)); }
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)); }
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)); }
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)); } }