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

Side by Side Diff: test/cctest/test-regexp.cc

Issue 2050343002: [regexp] Experimental support for regexp named captures (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 4 years, 6 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/regexp/regexp-parser.cc ('k') | test/mjsunit/harmony/regexp-named-captures.js » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 CHECK_MIN_MAX("a+b|c", 1, RegExpTree::kInfinity); 431 CHECK_MIN_MAX("a+b|c", 1, RegExpTree::kInfinity);
432 CHECK_MIN_MAX("(?:a{5,1000000}){3,1000000}", 15, RegExpTree::kInfinity); 432 CHECK_MIN_MAX("(?:a{5,1000000}){3,1000000}", 15, RegExpTree::kInfinity);
433 CHECK_MIN_MAX("(?:ab){4,7}", 8, 14); 433 CHECK_MIN_MAX("(?:ab){4,7}", 8, 14);
434 CHECK_MIN_MAX("a\\bc", 2, 2); 434 CHECK_MIN_MAX("a\\bc", 2, 2);
435 CHECK_MIN_MAX("a\\Bc", 2, 2); 435 CHECK_MIN_MAX("a\\Bc", 2, 2);
436 CHECK_MIN_MAX("a\\sc", 3, 3); 436 CHECK_MIN_MAX("a\\sc", 3, 3);
437 CHECK_MIN_MAX("a\\Sc", 3, 3); 437 CHECK_MIN_MAX("a\\Sc", 3, 3);
438 CHECK_MIN_MAX("a(?=b)c", 2, 2); 438 CHECK_MIN_MAX("a(?=b)c", 2, 2);
439 CHECK_MIN_MAX("a(?=bbb|bb)c", 2, 2); 439 CHECK_MIN_MAX("a(?=bbb|bb)c", 2, 2);
440 CHECK_MIN_MAX("a(?!bbb|bb)c", 2, 2); 440 CHECK_MIN_MAX("a(?!bbb|bb)c", 2, 2);
441
442 FLAG_harmony_regexp_named_captures = true;
443 CheckParseEq("(?<a>x)(?<b>x)(?<c>x)\\k<a>",
444 "(: (^ 'x') (^ 'x') (^ 'x') (<- 1))", true);
445 CheckParseEq("(?<a>x)(?<b>x)(?<c>x)\\k<b>",
446 "(: (^ 'x') (^ 'x') (^ 'x') (<- 2))", true);
447 CheckParseEq("(?<a>x)(?<b>x)(?<c>x)\\k<c>",
448 "(: (^ 'x') (^ 'x') (^ 'x') (<- 3))", true);
449 CheckParseEq("(?<a>a)\\k<a>", "(: (^ 'a') (<- 1))", true);
450 CheckParseEq("(?<a>a\\k<a>)", "(^ 'a')", true);
451 CheckParseEq("(?<a>\\k<a>a)", "(^ 'a')", true);
452 CheckParseEq("(?<a>\\k<b>)(?<b>\\k<a>)", "(: (^ (<- 2)) (^ (<- 1)))", true);
453 CheckParseEq("\\k<a>(?<a>a)", "(: (<- 1) (^ 'a'))", true);
454
455 CheckParseEq("(?<\\u{03C0}>a)", "(^ 'a')", true);
456 CheckParseEq("(?<\\u03C0>a)", "(^ 'a')", true);
457 FLAG_harmony_regexp_named_captures = false;
441 } 458 }
442 459
443 460
444 TEST(ParserWithLookbehind) { 461 TEST(ParserWithLookbehind) {
445 TestRegExpParser(true); // Lookbehind enabled. 462 TestRegExpParser(true); // Lookbehind enabled.
446 } 463 }
447 464
448 465
449 TEST(ParserWithoutLookbehind) { 466 TEST(ParserWithoutLookbehind) {
450 TestRegExpParser(true); // Lookbehind enabled. 467 TestRegExpParser(true); // Lookbehind enabled.
451 } 468 }
452 469
453
454 TEST(ParserRegression) { 470 TEST(ParserRegression) {
455 CheckParseEq("[A-Z$-][x]", "(! [A-Z $ -] [x])"); 471 CheckParseEq("[A-Z$-][x]", "(! [A-Z $ -] [x])");
456 CheckParseEq("a{3,4*}", "(: 'a{3,' (# 0 - g '4') '}')"); 472 CheckParseEq("a{3,4*}", "(: 'a{3,' (# 0 - g '4') '}')");
457 CheckParseEq("{", "'{'"); 473 CheckParseEq("{", "'{'");
458 CheckParseEq("a|", "(| 'a' %)"); 474 CheckParseEq("a|", "(| 'a' %)");
459 } 475 }
460 476
461 static void ExpectError(const char* input, 477 static void ExpectError(const char* input, const char* expected,
462 const char* expected) { 478 bool unicode = false) {
463 v8::HandleScope scope(CcTest::isolate()); 479 v8::HandleScope scope(CcTest::isolate());
464 Zone zone(CcTest::i_isolate()->allocator()); 480 Zone zone(CcTest::i_isolate()->allocator());
465 FlatStringReader reader(CcTest::i_isolate(), CStrVector(input)); 481 FlatStringReader reader(CcTest::i_isolate(), CStrVector(input));
466 RegExpCompileData result; 482 RegExpCompileData result;
467 CHECK(!v8::internal::RegExpParser::ParseRegExp( 483 JSRegExp::Flags flags = JSRegExp::kNone;
468 CcTest::i_isolate(), &zone, &reader, JSRegExp::kNone, &result)); 484 if (unicode) flags |= JSRegExp::kUnicode;
485 CHECK(!v8::internal::RegExpParser::ParseRegExp(CcTest::i_isolate(), &zone,
486 &reader, flags, &result));
469 CHECK(result.tree == NULL); 487 CHECK(result.tree == NULL);
470 CHECK(!result.error.is_null()); 488 CHECK(!result.error.is_null());
471 v8::base::SmartArrayPointer<char> str = result.error->ToCString(ALLOW_NULLS); 489 v8::base::SmartArrayPointer<char> str = result.error->ToCString(ALLOW_NULLS);
472 CHECK_EQ(0, strcmp(expected, str.get())); 490 CHECK_EQ(0, strcmp(expected, str.get()));
473 } 491 }
474 492
475 493
476 TEST(Errors) { 494 TEST(Errors) {
477 const char* kEndBackslash = "\\ at end of pattern"; 495 const char* kEndBackslash = "\\ at end of pattern";
478 ExpectError("\\", kEndBackslash); 496 ExpectError("\\", kEndBackslash);
(...skipping 13 matching lines...) Expand all
492 ExpectError("{1,}", kNothingToRepeat); 510 ExpectError("{1,}", kNothingToRepeat);
493 511
494 // Check that we don't allow more than kMaxCapture captures 512 // Check that we don't allow more than kMaxCapture captures
495 const int kMaxCaptures = 1 << 16; // Must match RegExpParser::kMaxCaptures. 513 const int kMaxCaptures = 1 << 16; // Must match RegExpParser::kMaxCaptures.
496 const char* kTooManyCaptures = "Too many captures"; 514 const char* kTooManyCaptures = "Too many captures";
497 std::ostringstream os; 515 std::ostringstream os;
498 for (int i = 0; i <= kMaxCaptures; i++) { 516 for (int i = 0; i <= kMaxCaptures; i++) {
499 os << "()"; 517 os << "()";
500 } 518 }
501 ExpectError(os.str().c_str(), kTooManyCaptures); 519 ExpectError(os.str().c_str(), kTooManyCaptures);
520
521 FLAG_harmony_regexp_named_captures = true;
522 const char* kInvalidCaptureName = "Invalid capture group name";
523 ExpectError("(?<>.)", kInvalidCaptureName, true);
524 ExpectError("(?<1>.)", kInvalidCaptureName, true);
525 ExpectError("(?<_%>.)", kInvalidCaptureName, true);
526 ExpectError("\\k<a", kInvalidCaptureName, true);
527 const char* kDuplicateCaptureName = "Duplicate capture group name";
528 ExpectError("(?<a>.)(?<a>.)", kDuplicateCaptureName, true);
529 const char* kInvalidUnicodeEscape = "Invalid Unicode escape sequence";
530 ExpectError("(?<\\u{FISK}", kInvalidUnicodeEscape, true);
531 const char* kInvalidCaptureReferenced = "Invalid named capture referenced";
532 ExpectError("\\k<a>", kInvalidCaptureReferenced, true);
533 ExpectError("(?<b>)\\k<a>", kInvalidCaptureReferenced, true);
534 const char* kInvalidNamedReference = "Invalid named reference";
535 ExpectError("\\ka", kInvalidNamedReference, true);
536 FLAG_harmony_regexp_named_captures = false;
502 } 537 }
503 538
504 539
505 static bool IsDigit(uc16 c) { 540 static bool IsDigit(uc16 c) {
506 return ('0' <= c && c <= '9'); 541 return ('0' <= c && c <= '9');
507 } 542 }
508 543
509 544
510 static bool NotDigit(uc16 c) { 545 static bool NotDigit(uc16 c) {
511 return !IsDigit(c); 546 return !IsDigit(c);
(...skipping 1477 matching lines...) Expand 10 before | Expand all | Expand 10 after
1989 v8::Local<v8::String> external = 2024 v8::Local<v8::String> external =
1990 v8::String::NewExternalOneByte(isolate, new UncachedExternalString()) 2025 v8::String::NewExternalOneByte(isolate, new UncachedExternalString())
1991 .ToLocalChecked(); 2026 .ToLocalChecked();
1992 CHECK(v8::Utils::OpenHandle(*external)->map() == 2027 CHECK(v8::Utils::OpenHandle(*external)->map() ==
1993 CcTest::i_isolate()->heap()->short_external_one_byte_string_map()); 2028 CcTest::i_isolate()->heap()->short_external_one_byte_string_map());
1994 v8::Local<v8::Object> global = env->Global(); 2029 v8::Local<v8::Object> global = env->Global();
1995 global->Set(env.local(), v8_str("external"), external).FromJust(); 2030 global->Set(env.local(), v8_str("external"), external).FromJust();
1996 CompileRun("var re = /y(.)/; re.test('ab');"); 2031 CompileRun("var re = /y(.)/; re.test('ab');");
1997 ExpectString("external.substring(1).match(re)[1]", "z"); 2032 ExpectString("external.substring(1).match(re)[1]", "z");
1998 } 2033 }
OLDNEW
« no previous file with comments | « src/regexp/regexp-parser.cc ('k') | test/mjsunit/harmony/regexp-named-captures.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698