private BoundNode BindFunctionDefinition(FunctionDefinitionSyntax declaration, Symbol parent) { BindAttributes(declaration.Attributes); var boundReturnType = Bind(declaration.ReturnType, x => BindType(x, parent)); var isQualifiedName = false; ContainerSymbol containerSymbol; Symbol functionOwner; switch (declaration.Name.Kind) { case SyntaxKind.IdentifierDeclarationName: containerSymbol = null; functionOwner = parent; break; case SyntaxKind.QualifiedDeclarationName: containerSymbol = LookupContainer(((QualifiedDeclarationNameSyntax) declaration.Name).Left); if (containerSymbol == null) return new BoundErrorNode(); isQualifiedName = true; functionOwner = containerSymbol; break; default: throw new InvalidOperationException(); } var containerBinder = containerSymbol?.Binder ?? this; var symbolTable = containerBinder.LocalSymbols; var functionSymbol = symbolTable .SelectMany(x => x.Value) .OfType<SourceFunctionSymbol>() .FirstOrDefault(x => SyntaxFacts.HaveMatchingSignatures( x.DefinitionSyntax as FunctionSyntax ?? x.DeclarationSyntaxes[0], declaration)); if (functionSymbol != null) { if (functionSymbol.DefinitionSyntax != null) Diagnostics.ReportSymbolRedefined(declaration.Name.GetTextSpanSafe(), functionSymbol); else functionSymbol.DefinitionSyntax = declaration; } else { if (isQualifiedName) Diagnostics.ReportUndeclaredFunctionInNamespaceOrClass((QualifiedDeclarationNameSyntax) declaration.Name); functionSymbol = new SourceFunctionSymbol(declaration, parent, boundReturnType.TypeSymbol); containerBinder.AddSymbol(functionSymbol, declaration.Name.GetTextSpanSafe(), true); } if (declaration.Semantic != null) Bind(declaration.Semantic, BindVariableQualifier); var functionBinder = (functionOwner != null && functionOwner.Kind == SymbolKind.Class) ? new ClassMethodBinder(_sharedBinderState, this, (ClassSymbol) functionOwner) : new Binder(_sharedBinderState, this); if (isQualifiedName) functionBinder = new ContainedFunctionBinder(_sharedBinderState, functionBinder, containerSymbol.Binder); var boundParameters = BindParameters(declaration.ParameterList, functionBinder, functionSymbol); var boundBody = functionBinder.Bind(declaration.Body, x => functionBinder.BindBlock(x, functionSymbol)); return new BoundFunctionDefinition(functionSymbol, boundReturnType, boundParameters.ToImmutableArray(), boundBody); }
private BoundNode BindFunctionDefinition(FunctionDefinitionSyntax declaration, Symbol parent) { BindAttributes(declaration.Attributes); var boundReturnType = Bind(declaration.ReturnType, x => BindType(x, parent)); var isQualifiedName = false; ContainerSymbol containerSymbol; Symbol functionOwner; switch (declaration.Name.Kind) { case SyntaxKind.IdentifierDeclarationName: containerSymbol = null; functionOwner = parent; break; case SyntaxKind.QualifiedDeclarationName: containerSymbol = LookupContainer(((QualifiedDeclarationNameSyntax)declaration.Name).Left); if (containerSymbol == null) { return(new BoundErrorNode()); } isQualifiedName = true; functionOwner = containerSymbol; break; default: throw new InvalidOperationException(); } var containerBinder = containerSymbol?.Binder ?? this; var symbolTable = containerBinder.LocalSymbols; var functionSymbol = symbolTable .SelectMany(x => x.Value) .OfType <SourceFunctionSymbol>() .FirstOrDefault(x => SyntaxFacts.HaveMatchingSignatures( x.DefinitionSyntax as FunctionSyntax ?? x.DeclarationSyntaxes[0], declaration)); if (functionSymbol != null) { if (functionSymbol.DefinitionSyntax != null) { Diagnostics.ReportSymbolRedefined(declaration.Name.SourceRange, functionSymbol); } else { functionSymbol.DefinitionSyntax = declaration; } } else { if (isQualifiedName) { Diagnostics.ReportUndeclaredFunctionInNamespaceOrClass((QualifiedDeclarationNameSyntax)declaration.Name); } functionSymbol = new SourceFunctionSymbol(declaration, parent, boundReturnType.TypeSymbol); containerBinder.AddSymbol(functionSymbol, declaration.Name.SourceRange, true); } if (declaration.Semantic != null) { Bind(declaration.Semantic, BindVariableQualifier); } var functionBinder = (functionOwner != null && functionOwner.Kind == SymbolKind.Class) ? new ClassMethodBinder(_sharedBinderState, this, (ClassSymbol)functionOwner) : new Binder(_sharedBinderState, this); if (isQualifiedName) { functionBinder = new ContainedFunctionBinder(_sharedBinderState, functionBinder, containerSymbol.Binder); } var boundParameters = BindParameters(declaration.ParameterList, functionBinder, functionSymbol); var boundBody = functionBinder.Bind(declaration.Body, x => functionBinder.BindBlock(x, functionSymbol)); return(new BoundFunctionDefinition(functionSymbol, boundReturnType, boundParameters.ToImmutableArray(), boundBody)); }