@@ -63,63 +63,124 @@ func (f *SymbolFormatter) Format(symbol string) (string, error) {
63
63
}
64
64
65
65
func (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 )
69
69
}
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
+ }
75
83
}
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 )
78
88
}
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 ) {
82
97
continue
83
98
}
84
- switch desc .Suffix {
99
+
100
+ switch descriptor .Suffix {
101
+ case Descriptor_Local :
102
+ b .WriteString (descriptor .Name )
85
103
case Descriptor_Namespace :
86
- descriptor .WriteString (desc .Name )
87
- descriptor .WriteRune ('/' )
104
+ writeSuffixedDescriptor (b , descriptor .Name , '/' )
88
105
case Descriptor_Type :
89
- descriptor .WriteString (desc .Name )
90
- descriptor .WriteRune ('#' )
106
+ writeSuffixedDescriptor (b , descriptor .Name , '#' )
91
107
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 , '.' )
109
109
case Descriptor_Meta :
110
- descriptor .WriteString (desc .Name )
111
- descriptor .WriteRune (':' )
110
+ writeSuffixedDescriptor (b , descriptor .Name , ':' )
112
111
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
117
145
}
118
146
}
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 )
122
154
}
123
155
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
+ }
125
186
}
0 commit comments