Starting from the token under the cursor move back and extract something that resembles a valid Go primary expression. Examples of primary expressions from Go spec: x 2 (s + ".txt") f(3.1415, true) Point{1, 2} m["foo"] s[i : j + 1] obj.color f.p[i].x() As you can see we can move through all of them
()
| 194 | // Of course there are also slightly more complicated rules for brackets: |
| 195 | // ident{}.ident()[5][4](), etc. |
| 196 | func (this *token_iterator) extract_go_expr() string { |
| 197 | orig := this.token_index |
| 198 | |
| 199 | // Contains the type of the previously scanned token (initialized with |
| 200 | // the token right under the cursor). This is the token to the *right* of |
| 201 | // the current one. |
| 202 | prev := this.token().tok |
| 203 | loop: |
| 204 | for { |
| 205 | if !this.go_back() { |
| 206 | return token_items_to_string(this.tokens[:orig]) |
| 207 | } |
| 208 | switch this.token().tok { |
| 209 | case token.PERIOD: |
| 210 | // If the '.' is not followed by IDENT, it's invalid. |
| 211 | if prev != token.IDENT { |
| 212 | break loop |
| 213 | } |
| 214 | case token.IDENT: |
| 215 | // Valid tokens after IDENT are '.', '[', '{' and '('. |
| 216 | switch prev { |
| 217 | case token.PERIOD, token.LBRACK, token.LBRACE, token.LPAREN: |
| 218 | // all ok |
| 219 | default: |
| 220 | break loop |
| 221 | } |
| 222 | case token.RBRACE: |
| 223 | // This one can only be a part of type initialization, like: |
| 224 | // Dummy{}.Hello() |
| 225 | // It is valid Go if Hello method is defined on a non-pointer receiver. |
| 226 | if prev != token.PERIOD { |
| 227 | break loop |
| 228 | } |
| 229 | this.skip_to_balanced_pair() |
| 230 | case token.RPAREN, token.RBRACK: |
| 231 | // After ']' and ')' their opening counterparts are valid '[', '(', |
| 232 | // as well as the dot. |
| 233 | switch prev { |
| 234 | case token.PERIOD, token.LBRACK, token.LPAREN: |
| 235 | // all ok |
| 236 | default: |
| 237 | break loop |
| 238 | } |
| 239 | this.skip_to_balanced_pair() |
| 240 | default: |
| 241 | break loop |
| 242 | } |
| 243 | prev = this.token().tok |
| 244 | } |
| 245 | expr := token_items_to_string(this.tokens[this.token_index+1 : orig]) |
| 246 | if *g_debug { |
| 247 | log.Printf("extracted expression tokens: %s", expr) |
| 248 | } |
| 249 | return expr |
| 250 | } |
| 251 | |
| 252 | // Given a slice of token_item, reassembles them into the original literal |
| 253 | // expression. |
no test coverage detected