Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(181)

Side by Side Diff: src/objects.cc

Issue 2775303002: [regexp] Named capture support for string replacements (Closed)
Patch Set: Only cast if not undefined Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/objects.h ('k') | src/runtime/runtime-regexp.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/objects.h" 5 #include "src/objects.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 #include <iomanip> 8 #include <iomanip>
9 #include <memory> 9 #include <memory>
10 #include <sstream> 10 #include <sstream>
(...skipping 11385 matching lines...) Expand 10 before | Expand all | Expand 10 after
11396 return SearchString<const uint8_t>(isolate, receiver_content, pat_vector, 11396 return SearchString<const uint8_t>(isolate, receiver_content, pat_vector,
11397 start_index); 11397 start_index);
11398 } 11398 }
11399 Vector<const uc16> pat_vector = search_content.ToUC16Vector(); 11399 Vector<const uc16> pat_vector = search_content.ToUC16Vector();
11400 return SearchString<const uc16>(isolate, receiver_content, pat_vector, 11400 return SearchString<const uc16>(isolate, receiver_content, pat_vector,
11401 start_index); 11401 start_index);
11402 } 11402 }
11403 11403
11404 MaybeHandle<String> String::GetSubstitution(Isolate* isolate, Match* match, 11404 MaybeHandle<String> String::GetSubstitution(Isolate* isolate, Match* match,
11405 Handle<String> replacement) { 11405 Handle<String> replacement) {
11406 DCHECK_IMPLIES(match->HasNamedCaptures(), FLAG_harmony_regexp_named_captures);
11407
11406 Factory* factory = isolate->factory(); 11408 Factory* factory = isolate->factory();
11407 11409
11408 const int replacement_length = replacement->length(); 11410 const int replacement_length = replacement->length();
11409 const int captures_length = match->CaptureCount(); 11411 const int captures_length = match->CaptureCount();
11410 11412
11411 replacement = String::Flatten(replacement); 11413 replacement = String::Flatten(replacement);
11412 11414
11413 Handle<String> dollar_string = 11415 Handle<String> dollar_string =
11414 factory->LookupSingleCharacterStringFromCode('$'); 11416 factory->LookupSingleCharacterStringFromCode('$');
11415 int next_dollar_ix = String::IndexOf(isolate, replacement, dollar_string, 0); 11417 int next_dollar_ix = String::IndexOf(isolate, replacement, dollar_string, 0);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
11482 11484
11483 bool capture_exists; 11485 bool capture_exists;
11484 Handle<String> capture; 11486 Handle<String> capture;
11485 ASSIGN_RETURN_ON_EXCEPTION( 11487 ASSIGN_RETURN_ON_EXCEPTION(
11486 isolate, capture, match->GetCapture(scaled_index, &capture_exists), 11488 isolate, capture, match->GetCapture(scaled_index, &capture_exists),
11487 String); 11489 String);
11488 if (capture_exists) builder.AppendString(capture); 11490 if (capture_exists) builder.AppendString(capture);
11489 continue_from_ix = peek_ix + advance; 11491 continue_from_ix = peek_ix + advance;
11490 break; 11492 break;
11491 } 11493 }
11494 case '<': { // $<name> - named capture
11495 if (!match->HasNamedCaptures()) {
11496 builder.AppendCharacter('$');
11497 continue_from_ix = peek_ix;
11498 break;
11499 }
11500
11501 Handle<String> bracket_string =
11502 factory->LookupSingleCharacterStringFromCode('>');
11503 const int closing_bracket_ix =
11504 String::IndexOf(isolate, replacement, bracket_string, peek_ix + 1);
11505
11506 if (closing_bracket_ix == -1) {
11507 THROW_NEW_ERROR(
11508 isolate,
11509 NewSyntaxError(MessageTemplate::kRegExpInvalidReplaceString,
11510 replacement),
11511 String);
11512 }
11513
11514 Handle<String> capture_name =
11515 factory->NewSubString(replacement, peek_ix + 1, closing_bracket_ix);
11516 bool capture_exists;
11517 Handle<String> capture;
11518 ASSIGN_RETURN_ON_EXCEPTION(
11519 isolate, capture,
11520 match->GetNamedCapture(capture_name, &capture_exists), String);
11521 if (capture_exists) builder.AppendString(capture);
11522 continue_from_ix = closing_bracket_ix + 1;
11523 break;
11524 }
11492 default: 11525 default:
11493 builder.AppendCharacter('$'); 11526 builder.AppendCharacter('$');
11494 continue_from_ix = peek_ix; 11527 continue_from_ix = peek_ix;
11495 break; 11528 break;
11496 } 11529 }
11497 11530
11498 // Go the the next $ in the replacement. 11531 // Go the the next $ in the replacement.
11499 // TODO(jgruber): Single-char lookups could be much more efficient. 11532 // TODO(jgruber): Single-char lookups could be much more efficient.
11500 DCHECK_NE(continue_from_ix, -1); 11533 DCHECK_NE(continue_from_ix, -1);
11501 next_dollar_ix = 11534 next_dollar_ix =
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
11652 if (Get(i) != unibrow::Utf16::TrailSurrogate(r)) return false; 11685 if (Get(i) != unibrow::Utf16::TrailSurrogate(r)) return false;
11653 } else { 11686 } else {
11654 if (Get(i) != r) return false; 11687 if (Get(i) != r) return false;
11655 } 11688 }
11656 utf8_data += cursor; 11689 utf8_data += cursor;
11657 remaining_in_str -= cursor; 11690 remaining_in_str -= cursor;
11658 } 11691 }
11659 return (allow_prefix_match || i == slen) && remaining_in_str == 0; 11692 return (allow_prefix_match || i == slen) && remaining_in_str == 0;
11660 } 11693 }
11661 11694
11695 template <>
11696 bool String::IsEqualTo(Vector<const uint8_t> str) {
11697 return IsOneByteEqualTo(str);
11698 }
11699
11700 template <>
11701 bool String::IsEqualTo(Vector<const uc16> str) {
11702 return IsTwoByteEqualTo(str);
11703 }
11662 11704
11663 bool String::IsOneByteEqualTo(Vector<const uint8_t> str) { 11705 bool String::IsOneByteEqualTo(Vector<const uint8_t> str) {
11664 int slen = length(); 11706 int slen = length();
11665 if (str.length() != slen) return false; 11707 if (str.length() != slen) return false;
11666 DisallowHeapAllocation no_gc; 11708 DisallowHeapAllocation no_gc;
11667 FlatContent content = GetFlatContent(); 11709 FlatContent content = GetFlatContent();
11668 if (content.IsOneByte()) { 11710 if (content.IsOneByte()) {
11669 return CompareChars(content.ToOneByteVector().start(), 11711 return CompareChars(content.ToOneByteVector().start(),
11670 str.start(), slen) == 0; 11712 str.start(), slen) == 0;
11671 } 11713 }
(...skipping 8644 matching lines...) Expand 10 before | Expand all | Expand 10 after
20316 // depend on this. 20358 // depend on this.
20317 return DICTIONARY_ELEMENTS; 20359 return DICTIONARY_ELEMENTS;
20318 } 20360 }
20319 DCHECK_LE(kind, LAST_ELEMENTS_KIND); 20361 DCHECK_LE(kind, LAST_ELEMENTS_KIND);
20320 return kind; 20362 return kind;
20321 } 20363 }
20322 } 20364 }
20323 20365
20324 } // namespace internal 20366 } // namespace internal
20325 } // namespace v8 20367 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/runtime/runtime-regexp.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698