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 static bool IsInterfaceMethod(SourceFunctionSymbol symbol) { return symbol.Parent != null && symbol.Parent.Kind == SymbolKind.Interface; }
private BoundFunctionDeclaration BindFunctionDeclaration(FunctionDeclarationSyntax declaration, Symbol parent) { BindAttributes(declaration.Attributes); var boundReturnType = Bind(declaration.ReturnType, x => BindType(x, parent)); var functionSymbol = LocalSymbols.OfType<SourceFunctionSymbol>() .FirstOrDefault(x => SyntaxFacts.HaveMatchingSignatures( x.DefinitionSyntax as FunctionSyntax ?? x.DeclarationSyntaxes[0], declaration)); if (functionSymbol != null) { functionSymbol.DeclarationSyntaxes.Add(declaration); } else { functionSymbol = new SourceFunctionSymbol(declaration, parent, boundReturnType.TypeSymbol); AddSymbol(functionSymbol, declaration.Name.GetTextSpanSafe(), true); } if (declaration.Semantic != null) Bind(declaration.Semantic, BindVariableQualifier); var functionBinder = new Binder(_sharedBinderState, this); var boundParameters = BindParameters(declaration.ParameterList, functionBinder, functionSymbol); return new BoundFunctionDeclaration(functionSymbol, boundReturnType, boundParameters.ToImmutableArray()); }