From df7f7ea8ab732289a130ca13631e3551f9a91dc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Ferr=C3=A0s?= Date: Tue, 17 Sep 2024 19:27:00 +0200 Subject: [PATCH] WIP displaying type size on hover. --- .../internal/lsp/server/TextDocumentHover.go | 89 ++++++++++++++++++- server/pkg/symbols/type.go | 4 + server/pkg/utils/arch.go | 31 +++++++ server/pkg/utils/features.go | 17 ++++ 4 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 server/pkg/utils/arch.go create mode 100644 server/pkg/utils/features.go diff --git a/server/internal/lsp/server/TextDocumentHover.go b/server/internal/lsp/server/TextDocumentHover.go index d8cdd18..fde8c3e 100644 --- a/server/internal/lsp/server/TextDocumentHover.go +++ b/server/internal/lsp/server/TextDocumentHover.go @@ -1,6 +1,8 @@ package server import ( + "fmt" + "github.com/pherrymason/c3-lsp/pkg/symbols" "github.com/pherrymason/c3-lsp/pkg/utils" "github.com/tliron/glsp" @@ -30,13 +32,98 @@ func (h *Server) TextDocumentHover(context *glsp.Context, params *protocol.Hover extraLine += "\n\nIn module **[" + foundSymbol.GetModuleString() + "]**" } + sizeInfo := "" + if utils.IsFeatureEnabled("SIZE_ON_HOVER") { + if hasSize(foundSymbol) { + sizeInfo = "// size = " + calculateSize(foundSymbol) + ", align = " + calculateAlignment(foundSymbol) + "\n" + } + } + hover := protocol.Hover{ Contents: protocol.MarkupContent{ Kind: protocol.MarkupKindMarkdown, - Value: "```c3" + "\n" + foundSymbol.GetHoverInfo() + "\n```" + + Value: "```c3" + "\n" + + sizeInfo + + foundSymbol.GetHoverInfo() + "\n```" + extraLine, }, } return &hover, nil } + +func hasSize(symbol symbols.Indexable) bool { + _, isVariable := symbol.(*symbols.Variable) + if isVariable { + return true + } + + _, isMember := symbol.(*symbols.StructMember) + if isMember { + return true + } + + _, isStruct := symbol.(*symbols.Struct) + if isStruct { + return true + } + + _, isBitStruct := symbol.(*symbols.Bitstruct) + if isBitStruct { + return true + } + + return false +} + +func calculateSize(symbol symbols.Indexable) string { + variable, isVariable := symbol.(*symbols.Variable) + if isVariable { + if variable.Type.IsPointer() { + return fmt.Sprintf("%d", utils.PointerSize()) + } + + if variable.Type.IsBaseTypeLanguage() { + return fmt.Sprintf("%d", getLanguageTypeSize(variable.Type.GetName())) + } + } + + member, isMember := symbol.(*symbols.StructMember) + if isMember { + if member.GetType().IsPointer() { + return fmt.Sprintf("%d", utils.PointerSize()) + } + + if member.GetType().IsBaseTypeLanguage() { + return fmt.Sprintf("%d", getLanguageTypeSize(member.GetType().GetName())) + } + } + + return "?" +} + +func calculateAlignment(symbol symbols.Indexable) string { + return "" +} + +func getLanguageTypeSize(typeName string) uint { + size := uint(0) + switch typeName { + case "bool": + size = 1 + case "ichar", "char": + size = 8 + case "short", "ushort": + size = 16 + case "int", "uint": + size = 32 + case "long", "ulong": + size = 64 + case "int128", "uint128": + size = 128 + case "iptr", "uptr", "isz", "usz": + size = 0 + } + + return size +} diff --git a/server/pkg/symbols/type.go b/server/pkg/symbols/type.go index 628dd24..92c0509 100644 --- a/server/pkg/symbols/type.go +++ b/server/pkg/symbols/type.go @@ -52,6 +52,10 @@ func (t *Type) SetModule(module string) { t.module = module } +func (t *Type) IsPointer() bool { + return t.pointer > 0 +} + func (t Type) String() string { pointerStr := strings.Repeat("*", t.pointer) optionalStr := "" diff --git a/server/pkg/utils/arch.go b/server/pkg/utils/arch.go new file mode 100644 index 0000000..335747f --- /dev/null +++ b/server/pkg/utils/arch.go @@ -0,0 +1,31 @@ +package utils + +import ( + "runtime" +) + +const ( + CPU_UNKNOWN = iota + CPU_64 = 64 + CPU_32 = 32 +) + +func CpuArchitecture() uint { + if runtime.GOARCH == "amd64" || runtime.GOARCH == "arm64" { + return CPU_64 + } else if runtime.GOARCH == "386" || runtime.GOARCH == "arm" { + return CPU_32 + } + + return CPU_UNKNOWN +} + +func PointerSize() uint { + arch := CpuArchitecture() + + if arch != CPU_UNKNOWN { + return arch / 8 + } + + return 0 +} diff --git a/server/pkg/utils/features.go b/server/pkg/utils/features.go new file mode 100644 index 0000000..6ddf3b2 --- /dev/null +++ b/server/pkg/utils/features.go @@ -0,0 +1,17 @@ +package utils + +func getFeatureFlags() map[string]bool { + return map[string]bool{ + "SIZE_ON_HOVER": false, + } +} + +// Function to check if a specific feature is enabled +func IsFeatureEnabled(feature string) bool { + flags := getFeatureFlags() + if enabled, exists := flags[feature]; exists { + return enabled + } + // Default behavior if feature flag is not found + return false +}