@@ -63,63 +63,124 @@ func (f *SymbolFormatter) Format(symbol string) (string, error) {
6363}
6464
6565func (f * SymbolFormatter ) FormatSymbol (symbol * Symbol ) string {
66- var parts [] string
67- if f .IncludeScheme (symbol .Scheme ) { // Always include the scheme for local symbols
68- parts = append ( parts , symbol .Scheme )
66+ b := & strings. Builder {}
67+ if f .IncludeScheme (symbol .Scheme ) {
68+ writeEscapedPackage ( b , symbol .Scheme )
6969 }
70- if symbol .Package != nil && symbol .Package .Manager != "" && f .IncludePackageManager (symbol .Package .Manager ) {
71- parts = append (parts , symbol .Package .Manager )
72- }
73- if symbol .Package != nil && symbol .Package .Name != "" && f .IncludePackageName (symbol .Package .Name ) {
74- parts = append (parts , symbol .Package .Name )
70+ if symbol .Package != nil {
71+ if f .IncludePackageManager (symbol .Package .Manager ) {
72+ buffer (b )
73+ writeEscapedPackage (b , symbol .Package .Manager )
74+ }
75+ if f .IncludePackageName (symbol .Package .Name ) {
76+ buffer (b )
77+ writeEscapedPackage (b , symbol .Package .Name )
78+ }
79+ if f .IncludePackageVersion (symbol .Package .Version ) {
80+ buffer (b )
81+ writeEscapedPackage (b , symbol .Package .Version )
82+ }
7583 }
76- if symbol .Package != nil && symbol .Package .Version != "" && f .IncludePackageVersion (symbol .Package .Version ) {
77- parts = append (parts , symbol .Package .Version )
84+
85+ if descriptorString := f .FormatDescriptors (symbol .Descriptors ); f .IncludeDescriptor (descriptorString ) {
86+ buffer (b )
87+ b .WriteString (descriptorString )
7888 }
79- descriptor := strings.Builder {}
80- for _ , desc := range symbol .Descriptors {
81- if ! f .IncludeRawDescriptor (desc ) {
89+
90+ return b .String ()
91+ }
92+
93+ func (f * SymbolFormatter ) FormatDescriptors (descriptors []* Descriptor ) string {
94+ b := & strings.Builder {}
95+ for _ , descriptor := range descriptors {
96+ if ! f .IncludeRawDescriptor (descriptor ) {
8297 continue
8398 }
84- switch desc .Suffix {
99+
100+ switch descriptor .Suffix {
101+ case Descriptor_Local :
102+ b .WriteString (descriptor .Name )
85103 case Descriptor_Namespace :
86- descriptor .WriteString (desc .Name )
87- descriptor .WriteRune ('/' )
104+ writeSuffixedDescriptor (b , descriptor .Name , '/' )
88105 case Descriptor_Type :
89- descriptor .WriteString (desc .Name )
90- descriptor .WriteRune ('#' )
106+ writeSuffixedDescriptor (b , descriptor .Name , '#' )
91107 case Descriptor_Term :
92- descriptor .WriteString (desc .Name )
93- descriptor .WriteRune ('.' )
94- case Descriptor_Method :
95- descriptor .WriteString (desc .Name )
96- descriptor .WriteRune ('(' )
97- if f .IncludeDisambiguator (desc .Disambiguator ) {
98- descriptor .WriteString (desc .Disambiguator )
99- }
100- descriptor .WriteString (")." )
101- case Descriptor_TypeParameter :
102- descriptor .WriteRune ('[' )
103- descriptor .WriteString (desc .Name )
104- descriptor .WriteRune (']' )
105- case Descriptor_Parameter :
106- descriptor .WriteRune ('(' )
107- descriptor .WriteString (desc .Name )
108- descriptor .WriteRune (')' )
108+ writeSuffixedDescriptor (b , descriptor .Name , '.' )
109109 case Descriptor_Meta :
110- descriptor .WriteString (desc .Name )
111- descriptor .WriteRune (':' )
110+ writeSuffixedDescriptor (b , descriptor .Name , ':' )
112111 case Descriptor_Macro :
113- descriptor .WriteString (desc .Name )
114- descriptor .WriteRune ('!' )
115- case Descriptor_Local :
116- descriptor .WriteString (desc .Name )
112+ writeSuffixedDescriptor (b , descriptor .Name , '!' )
113+ case Descriptor_TypeParameter :
114+ writeSandwichedDescriptor (b , '[' , descriptor .Name , ']' )
115+ case Descriptor_Parameter :
116+ writeSandwichedDescriptor (b , '(' , descriptor .Name , ')' )
117+
118+ case Descriptor_Method :
119+ if f .IncludeDisambiguator (descriptor .Disambiguator ) {
120+ writeSuffixedDescriptor (b , descriptor .Name , '(' )
121+ writeSuffixedDescriptor (b , descriptor .Disambiguator , ')' , '.' )
122+ } else {
123+ writeSuffixedDescriptor (b , descriptor .Name , '(' , ')' , '.' )
124+ }
125+ }
126+ }
127+
128+ return b .String ()
129+ }
130+
131+ func writeEscapedPackage (b * strings.Builder , name string ) {
132+ if name == "" {
133+ name = "."
134+ }
135+
136+ writeGenericEscapedIdentifier (b , name , ' ' )
137+ }
138+
139+ func writeSuffixedDescriptor (b * strings.Builder , identifier string , suffixes ... rune ) {
140+ escape := false
141+ for _ , ch := range identifier {
142+ if ! isIdentifierCharacter (ch ) {
143+ escape = true
144+ break
117145 }
118146 }
119- descriptorString := descriptor .String ()
120- if f .IncludeDescriptor (descriptorString ) {
121- parts = append (parts , descriptorString )
147+
148+ if escape {
149+ b .WriteRune ('`' )
150+ writeGenericEscapedIdentifier (b , identifier , '`' )
151+ b .WriteRune ('`' )
152+ } else {
153+ b .WriteString (identifier )
122154 }
123155
124- return strings .Join (parts , " " )
156+ for _ , suffix := range suffixes {
157+ b .WriteRune (suffix )
158+ }
159+ }
160+
161+ func writeSandwichedDescriptor (b * strings.Builder , prefix rune , identifier string , suffixes ... rune ) {
162+ b .WriteRune (prefix )
163+ writeSuffixedDescriptor (b , identifier , suffixes ... )
164+ }
165+
166+ func writeGenericEscapedIdentifier (b * strings.Builder , identifier string , escape rune ) {
167+ for {
168+ idx := strings .IndexRune (identifier , escape )
169+ if idx < 0 {
170+ break
171+ }
172+
173+ b .WriteString (identifier [:idx ])
174+ b .WriteRune (escape )
175+ b .WriteRune (escape )
176+ identifier = identifier [idx + 1 :]
177+ }
178+
179+ b .WriteString (identifier )
180+ }
181+
182+ func buffer (b * strings.Builder ) {
183+ if b .Len () > 0 {
184+ b .WriteRune (' ' )
185+ }
125186}
0 commit comments