diff --git a/cmd/lsp/definition.go b/cmd/lsp/definition.go index 1929db1..f2adb88 100644 --- a/cmd/lsp/definition.go +++ b/cmd/lsp/definition.go @@ -75,25 +75,32 @@ func getDefinitionToken(resolver fuckoff.Resolver, token *ast.Token) []protocol. method = resolver.GetMethod(s, token.String(), true) } - if method != nil { - return newDefinition(method) + if method == nil { + _, field := s.GetStaticField(token.String()) + if field == nil { + _, field = s.GetField(token.String()) + } + + if field != nil { + if _, ok := ast.As[*ast.Func](field.Type); ok { + return newDefinition(field) + } + } } + + return newDefinition(method) } else { _, field := s.GetField(token.String()) if field == nil { _, field = s.GetStaticField(token.String()) } - if field != nil { - return newDefinition(field) - } + return newDefinition(field) } } else if e, ok := ast.As[*ast.Enum](parent.Value.Result().Type); ok { case_ := e.GetCase(token.String()) - if case_ != nil { - return newDefinition(case_) - } + return newDefinition(case_) } case *ast.InitField: diff --git a/cmd/lsp/highlighter.go b/cmd/lsp/highlighter.go index f1793d7..616ad24 100644 --- a/cmd/lsp/highlighter.go +++ b/cmd/lsp/highlighter.go @@ -206,7 +206,11 @@ func (h *highlighter) VisitMember(expr *ast.Member) { } else if i, ok := expr.Value.(*ast.Identifier); ok && i.Kind == ast.EnumKind { h.add(expr.Name, enumMemberKind) } else { - h.add(expr.Name, propertyKind) + if _, ok := ast.As[*ast.Func](expr.Result().Type); ok { + h.add(expr.Name, functionKind) + } else { + h.add(expr.Name, propertyKind) + } } expr.AcceptChildren(h) diff --git a/cmd/lsp/hover.go b/cmd/lsp/hover.go index 67bbe5f..c82e9a6 100644 --- a/cmd/lsp/hover.go +++ b/cmd/lsp/hover.go @@ -64,6 +64,17 @@ func getHoverToken(resolver fuckoff.Resolver, token *ast.Token) *protocol.Hover method = resolver.GetMethod(s, token.String(), true) } + if method == nil { + _, field := s.GetStaticField(token.String()) + if field == nil { + _, field = s.GetField(token.String()) + } + + if f, ok := ast.As[*ast.Func](field.Type); ok { + method = f + } + } + if method != nil { return newHover(token, method.Signature(true)) } diff --git a/core/checker/expressions.go b/core/checker/expressions.go index 77cabbe..a696e7f 100644 --- a/core/checker/expressions.go +++ b/core/checker/expressions.go @@ -789,10 +789,17 @@ func (c *checker) VisitMember(expr *ast.Member) { function := c.resolver.GetMethod(v, expr.Name.String(), true) if function == nil { - c.error(expr.Name, "Struct '%s' does not contain static method with the name '%s'", ast.PrintType(v), expr.Name) - expr.Result().SetInvalid() + _, field := v.GetStaticField(expr.Name.String()) - return + if f, ok := ast.As[*ast.Func](field.Type); ok { + expr.Result().SetValue(f, ast.AssignableFlag|ast.AddressableFlag) + return + } else { + c.error(expr.Name, "Struct '%s' does not contain static method with the name '%s'", ast.PrintType(v), expr.Name) + expr.Result().SetInvalid() + + return + } } expr.Result().SetFunction(function) @@ -856,13 +863,21 @@ func (c *checker) VisitMember(expr *ast.Member) { if parentWantsFunction(expr) { function := c.resolver.GetMethod(s, expr.Name.String(), false) - if function != nil { - expr.Result().SetFunction(function) - } else { - c.error(expr.Name, "Struct '%s' does not contain method '%s'", ast.PrintType(s), expr.Name) - expr.Result().SetInvalid() + if function == nil { + _, field := s.GetField(expr.Name.String()) + + if f, ok := ast.As[*ast.Func](field.Type); ok { + expr.Result().SetValue(f, ast.AssignableFlag|ast.AddressableFlag) + return + } else { + c.error(expr.Name, "Struct '%s' does not contain method '%s'", ast.PrintType(s), expr.Name) + expr.Result().SetInvalid() + + return + } } + expr.Result().SetFunction(function) return }