| 246 | } |
| 247 | |
| 248 | Vector<uint8_t> GDScriptTokenizerBuffer::parse_code_string(const String &p_code, CompressMode p_compress_mode) { |
| 249 | HashMap<StringName, uint32_t> identifier_map; |
| 250 | HashMap<Variant, uint32_t, VariantHasher, VariantComparator> constant_map; |
| 251 | Vector<uint8_t> token_buffer; |
| 252 | HashMap<uint32_t, uint32_t> token_lines; |
| 253 | HashMap<uint32_t, uint32_t> token_columns; |
| 254 | |
| 255 | GDScriptTokenizerText tokenizer; |
| 256 | tokenizer.set_source_code(p_code); |
| 257 | tokenizer.set_multiline_mode(true); // Ignore whitespace tokens. |
| 258 | Token current = tokenizer.scan(); |
| 259 | int token_pos = 0; |
| 260 | int last_token_line = 0; |
| 261 | int token_counter = 0; |
| 262 | |
| 263 | while (current.type != Token::TK_EOF) { |
| 264 | int token_len = _token_to_binary(current, token_buffer, token_pos, identifier_map, constant_map); |
| 265 | token_pos += token_len; |
| 266 | if (token_counter > 0 && current.start_line > last_token_line) { |
| 267 | token_lines[token_counter] = current.start_line; |
| 268 | token_columns[token_counter] = current.start_column; |
| 269 | } |
| 270 | last_token_line = current.end_line; |
| 271 | |
| 272 | current = tokenizer.scan(); |
| 273 | token_counter++; |
| 274 | } |
| 275 | |
| 276 | // Reverse maps. |
| 277 | Vector<StringName> rev_identifier_map; |
| 278 | rev_identifier_map.resize(identifier_map.size()); |
| 279 | for (const KeyValue<StringName, uint32_t> &E : identifier_map) { |
| 280 | rev_identifier_map.write[E.value] = E.key; |
| 281 | } |
| 282 | Vector<Variant> rev_constant_map; |
| 283 | rev_constant_map.resize(constant_map.size()); |
| 284 | for (const KeyValue<Variant, uint32_t> &E : constant_map) { |
| 285 | rev_constant_map.write[E.value] = E.key; |
| 286 | } |
| 287 | HashMap<uint32_t, uint32_t> rev_token_lines; |
| 288 | for (const KeyValue<uint32_t, uint32_t> &E : token_lines) { |
| 289 | rev_token_lines[E.value] = E.key; |
| 290 | } |
| 291 | |
| 292 | // Remove continuation lines from map. |
| 293 | for (int line : tokenizer.get_continuation_lines()) { |
| 294 | if (rev_token_lines.has(line)) { |
| 295 | token_lines.erase(rev_token_lines[line]); |
| 296 | token_columns.erase(rev_token_lines[line]); |
| 297 | } |
| 298 | } |
| 299 | |
| 300 | Vector<uint8_t> contents; |
| 301 | contents.resize(16); |
| 302 | encode_uint32(identifier_map.size(), &contents.write[0]); |
| 303 | encode_uint32(constant_map.size(), &contents.write[4]); |
| 304 | encode_uint32(token_lines.size(), &contents.write[8]); |
| 305 | encode_uint32(token_counter, &contents.write[12]); |
no test coverage detected