Conditions | 31 |
Total Lines | 121 |
Code Lines | 76 |
Lines | 0 |
Ratio | 0 % |
Changes | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like filetype.Builder.Build often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | // Copyright 2019 The Go Authors. All rights reserved. |
||
122 | func (tb Builder) Build() (out Out) { |
||
123 | // Replace the resolver with one that resolves dependencies by index, |
||
124 | // which is faster and more reliable than relying on the global registry. |
||
125 | if tb.File.FileRegistry == nil { |
||
126 | tb.File.FileRegistry = preg.GlobalFiles |
||
127 | } |
||
128 | tb.File.FileRegistry = &resolverByIndex{ |
||
129 | goTypes: tb.GoTypes, |
||
130 | depIdxs: tb.DependencyIndexes, |
||
131 | fileRegistry: tb.File.FileRegistry, |
||
132 | } |
||
133 | |||
134 | // Initialize registry if unpopulated. |
||
135 | if tb.TypeRegistry == nil { |
||
136 | tb.TypeRegistry = preg.GlobalTypes |
||
137 | } |
||
138 | |||
139 | fbOut := tb.File.Build() |
||
140 | out.File = fbOut.File |
||
141 | |||
142 | // Process enums. |
||
143 | enumGoTypes := tb.GoTypes[:len(fbOut.Enums)] |
||
144 | if len(tb.EnumInfos) != len(fbOut.Enums) { |
||
145 | panic("mismatching enum lengths") |
||
146 | } |
||
147 | if len(fbOut.Enums) > 0 { |
||
148 | for i := range fbOut.Enums { |
||
149 | tb.EnumInfos[i] = pimpl.EnumInfo{ |
||
150 | GoReflectType: reflect.TypeOf(enumGoTypes[i]), |
||
151 | Desc: &fbOut.Enums[i], |
||
152 | } |
||
153 | // Register enum types. |
||
154 | if err := tb.TypeRegistry.RegisterEnum(&tb.EnumInfos[i]); err != nil { |
||
155 | panic(err) |
||
156 | } |
||
157 | } |
||
158 | } |
||
159 | |||
160 | // Process messages. |
||
161 | messageGoTypes := tb.GoTypes[len(fbOut.Enums):][:len(fbOut.Messages)] |
||
162 | if len(tb.MessageInfos) != len(fbOut.Messages) { |
||
163 | panic("mismatching message lengths") |
||
164 | } |
||
165 | if len(fbOut.Messages) > 0 { |
||
166 | for i := range fbOut.Messages { |
||
167 | if messageGoTypes[i] == nil { |
||
168 | continue // skip map entry |
||
169 | } |
||
170 | |||
171 | tb.MessageInfos[i].GoReflectType = reflect.TypeOf(messageGoTypes[i]) |
||
172 | tb.MessageInfos[i].Desc = &fbOut.Messages[i] |
||
173 | |||
174 | // Register message types. |
||
175 | if err := tb.TypeRegistry.RegisterMessage(&tb.MessageInfos[i]); err != nil { |
||
176 | panic(err) |
||
177 | } |
||
178 | } |
||
179 | |||
180 | // As a special-case for descriptor.proto, |
||
181 | // locally register concrete message type for the options. |
||
182 | if out.File.Path() == "google/protobuf/descriptor.proto" && out.File.Package() == "google.protobuf" { |
||
183 | for i := range fbOut.Messages { |
||
184 | switch fbOut.Messages[i].Name() { |
||
185 | case "FileOptions": |
||
186 | descopts.File = messageGoTypes[i].(pref.ProtoMessage) |
||
187 | case "EnumOptions": |
||
188 | descopts.Enum = messageGoTypes[i].(pref.ProtoMessage) |
||
189 | case "EnumValueOptions": |
||
190 | descopts.EnumValue = messageGoTypes[i].(pref.ProtoMessage) |
||
191 | case "MessageOptions": |
||
192 | descopts.Message = messageGoTypes[i].(pref.ProtoMessage) |
||
193 | case "FieldOptions": |
||
194 | descopts.Field = messageGoTypes[i].(pref.ProtoMessage) |
||
195 | case "OneofOptions": |
||
196 | descopts.Oneof = messageGoTypes[i].(pref.ProtoMessage) |
||
197 | case "ExtensionRangeOptions": |
||
198 | descopts.ExtensionRange = messageGoTypes[i].(pref.ProtoMessage) |
||
199 | case "ServiceOptions": |
||
200 | descopts.Service = messageGoTypes[i].(pref.ProtoMessage) |
||
201 | case "MethodOptions": |
||
202 | descopts.Method = messageGoTypes[i].(pref.ProtoMessage) |
||
203 | } |
||
204 | } |
||
205 | } |
||
206 | } |
||
207 | |||
208 | // Process extensions. |
||
209 | if len(tb.ExtensionInfos) != len(fbOut.Extensions) { |
||
210 | panic("mismatching extension lengths") |
||
211 | } |
||
212 | var depIdx int32 |
||
213 | for i := range fbOut.Extensions { |
||
214 | // For enum and message kinds, determine the referent Go type so |
||
215 | // that we can construct their constructors. |
||
216 | const listExtDeps = 2 |
||
217 | var goType reflect.Type |
||
218 | switch fbOut.Extensions[i].L1.Kind { |
||
219 | case pref.EnumKind: |
||
220 | j := depIdxs.Get(tb.DependencyIndexes, listExtDeps, depIdx) |
||
221 | goType = reflect.TypeOf(tb.GoTypes[j]) |
||
222 | depIdx++ |
||
223 | case pref.MessageKind, pref.GroupKind: |
||
224 | j := depIdxs.Get(tb.DependencyIndexes, listExtDeps, depIdx) |
||
225 | goType = reflect.TypeOf(tb.GoTypes[j]) |
||
226 | depIdx++ |
||
227 | default: |
||
228 | goType = goTypeForPBKind[fbOut.Extensions[i].L1.Kind] |
||
229 | } |
||
230 | if fbOut.Extensions[i].IsList() { |
||
231 | goType = reflect.SliceOf(goType) |
||
232 | } |
||
233 | |||
234 | pimpl.InitExtensionInfo(&tb.ExtensionInfos[i], &fbOut.Extensions[i], goType) |
||
235 | |||
236 | // Register extension types. |
||
237 | if err := tb.TypeRegistry.RegisterExtension(&tb.ExtensionInfos[i]); err != nil { |
||
238 | panic(err) |
||
239 | } |
||
240 | } |
||
241 | |||
242 | return out |
||
243 | } |
||
298 |