Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15410846
D8261.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
8 KB
Referenced Files
None
Subscribers
None
D8261.diff
View Options
Index: src/__phutil_library_map__.php
===================================================================
--- src/__phutil_library_map__.php
+++ src/__phutil_library_map__.php
@@ -355,6 +355,8 @@
'DifferentialCommitsFieldSpecification' => 'applications/differential/field/specification/DifferentialCommitsFieldSpecification.php',
'DifferentialConflictsFieldSpecification' => 'applications/differential/field/specification/DifferentialConflictsFieldSpecification.php',
'DifferentialController' => 'applications/differential/controller/DifferentialController.php',
+ 'DifferentialCustomFieldDependsOnParser' => 'applications/differential/field/parser/DifferentialCustomFieldDependsOnParser.php',
+ 'DifferentialCustomFieldDependsOnParserTestCase' => 'applications/differential/field/parser/__tests__/DifferentialCustomFieldDependsOnParserTestCase.php',
'DifferentialCustomFieldNumericIndex' => 'applications/differential/storage/DifferentialCustomFieldNumericIndex.php',
'DifferentialCustomFieldStorage' => 'applications/differential/storage/DifferentialCustomFieldStorage.php',
'DifferentialCustomFieldStringIndex' => 'applications/differential/storage/DifferentialCustomFieldStringIndex.php',
@@ -1369,6 +1371,7 @@
'PhabricatorCustomFieldIndexStorage' => 'infrastructure/customfield/storage/PhabricatorCustomFieldIndexStorage.php',
'PhabricatorCustomFieldInterface' => 'infrastructure/customfield/interface/PhabricatorCustomFieldInterface.php',
'PhabricatorCustomFieldList' => 'infrastructure/customfield/field/PhabricatorCustomFieldList.php',
+ 'PhabricatorCustomFieldMonogramParser' => 'infrastructure/customfield/parser/PhabricatorCustomFieldMonogramParser.php',
'PhabricatorCustomFieldNotAttachedException' => 'infrastructure/customfield/exception/PhabricatorCustomFieldNotAttachedException.php',
'PhabricatorCustomFieldNotProxyException' => 'infrastructure/customfield/exception/PhabricatorCustomFieldNotProxyException.php',
'PhabricatorCustomFieldNumericIndexStorage' => 'infrastructure/customfield/storage/PhabricatorCustomFieldNumericIndexStorage.php',
@@ -2870,6 +2873,8 @@
'DifferentialCommitsFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialConflictsFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialController' => 'PhabricatorController',
+ 'DifferentialCustomFieldDependsOnParser' => 'PhabricatorCustomFieldMonogramParser',
+ 'DifferentialCustomFieldDependsOnParserTestCase' => 'PhabricatorTestCase',
'DifferentialCustomFieldNumericIndex' => 'PhabricatorCustomFieldNumericIndexStorage',
'DifferentialCustomFieldStorage' => 'PhabricatorCustomFieldStorage',
'DifferentialCustomFieldStringIndex' => 'PhabricatorCustomFieldStringIndexStorage',
@@ -4053,6 +4058,7 @@
'PhabricatorCustomFieldImplementationIncompleteException' => 'Exception',
'PhabricatorCustomFieldIndexStorage' => 'PhabricatorLiskDAO',
'PhabricatorCustomFieldList' => 'Phobject',
+ 'PhabricatorCustomFieldMonogramParser' => 'Phobject',
'PhabricatorCustomFieldNotAttachedException' => 'Exception',
'PhabricatorCustomFieldNotProxyException' => 'Exception',
'PhabricatorCustomFieldNumericIndexStorage' => 'PhabricatorCustomFieldIndexStorage',
Index: src/applications/differential/field/parser/DifferentialCustomFieldDependsOnParser.php
===================================================================
--- /dev/null
+++ src/applications/differential/field/parser/DifferentialCustomFieldDependsOnParser.php
@@ -0,0 +1,32 @@
+<?php
+
+final class DifferentialCustomFieldDependsOnParser
+ extends PhabricatorCustomFieldMonogramParser {
+
+ protected function getPrefixes() {
+ return array(
+ 'depends on',
+ );
+ }
+
+ protected function getInfixes() {
+ return array(
+ 'diff',
+ 'diffs',
+ 'change',
+ 'changes',
+ 'rev',
+ 'revs',
+ 'revision',
+ );
+ }
+
+ protected function getSuffixes() {
+ return array();
+ }
+
+ protected function getMonogramPattern() {
+ return 'D\d+';
+ }
+
+}
Index: src/applications/differential/field/parser/__tests__/DifferentialCustomFieldDependsOnParserTestCase.php
===================================================================
--- /dev/null
+++ src/applications/differential/field/parser/__tests__/DifferentialCustomFieldDependsOnParserTestCase.php
@@ -0,0 +1,64 @@
+<?php
+
+final class DifferentialCustomFieldDependsOnParserTestCase
+ extends PhabricatorTestCase {
+
+ public function testParser() {
+ $map = array(
+ 'quack quack quack' => array(),
+ 'D123' => array(),
+ 'depends on D123' => array(
+ array(
+ 'match' => 'depends on D123',
+ 'prefix' => 'depends on',
+ 'infix' => '',
+ 'monograms' => array('D123'),
+ 'suffix' => '',
+ 'offset' => 0,
+ ),
+ ),
+ 'depends on D123.' => array(
+ array(
+ 'match' => 'depends on D123',
+ 'prefix' => 'depends on',
+ 'infix' => '',
+ 'monograms' => array('D123'),
+ 'suffix' => '',
+ 'offset' => 0,
+ ),
+ ),
+ 'depends on D123, D124' => array(
+ array(
+ 'match' => 'depends on D123, D124',
+ 'prefix' => 'depends on',
+ 'infix' => '',
+ 'monograms' => array('D123', 'D124'),
+ 'suffix' => '',
+ 'offset' => 0,
+ ),
+ ),
+ 'depends on rev D123' => array(
+ array(
+ 'match' => 'depends on rev D123',
+ 'prefix' => 'depends on',
+ 'infix' => 'rev',
+ 'monograms' => array('D123'),
+ 'suffix' => '',
+ 'offset' => 0,
+ ),
+ ),
+ 'depends on duck' => array(
+ ),
+ 'depends on D123abc' => array(
+ ),
+ );
+
+ foreach ($map as $input => $expect) {
+ $parser = new DifferentialCustomFieldDependsOnParser();
+ $output = $parser->parseCorpus($input);
+
+ $this->assertEqual($expect, $output, $input);
+ }
+ }
+
+}
Index: src/infrastructure/customfield/parser/PhabricatorCustomFieldMonogramParser.php
===================================================================
--- /dev/null
+++ src/infrastructure/customfield/parser/PhabricatorCustomFieldMonogramParser.php
@@ -0,0 +1,71 @@
+<?php
+
+abstract class PhabricatorCustomFieldMonogramParser
+ extends Phobject {
+
+ abstract protected function getPrefixes();
+ abstract protected function getSuffixes();
+ abstract protected function getInfixes();
+ abstract protected function getMonogramPattern();
+
+ public function parseCorpus($corpus) {
+ $prefixes = $this->getPrefixes();
+ $suffixes = $this->getSuffixes();
+ $infixes = $this->getInfixes();
+
+ $prefix_regex = $this->buildRegex($prefixes);
+ $infix_regex = $this->buildRegex($infixes, true);
+ $suffix_regex = $this->buildRegex($suffixes, true, true);
+
+ $monogram_pattern = $this->getMonogramPattern();
+
+ $pattern =
+ '/'.
+ '(?:^|\b)'.
+ $prefix_regex.
+ $infix_regex.
+ '((?:'.$monogram_pattern.'[,\s]*)+)'.
+ $suffix_regex.
+ '(?:$|\b)'.
+ '/i';
+
+ $matches = null;
+ $ok = preg_match_all(
+ $pattern,
+ $corpus,
+ $matches,
+ PREG_SET_ORDER | PREG_OFFSET_CAPTURE);
+
+ if ($ok === false) {
+ throw new Exception(pht('Regular expression "%s" is invalid!', $pattern));
+ }
+
+ $results = array();
+ foreach ($matches as $set) {
+ $results[] = array(
+ 'match' => $set[0][0],
+ 'prefix' => $set[1][0],
+ 'infix' => $set[2][0],
+ 'monograms' => array_filter(preg_split('/[,\s]+/', $set[3][0])),
+ 'suffix' => $set[4][0],
+ 'offset' => $set[0][1],
+ );
+ }
+
+ return $results;
+ }
+
+ private function buildRegex(array $list, $optional = false, $final = false) {
+ $parts = array();
+ foreach ($list as $string) {
+ $parts[] = preg_quote($string, '/');
+ }
+ $parts = implode('|', $parts);
+
+ $maybe_tail = $final ? '' : '\s+';
+ $maybe_optional = $optional ? '?' : '';
+
+ return '(?:('.$parts.')'.$maybe_tail.')'.$maybe_optional;
+ }
+
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mar 20 2025, 8:33 AM (4 w, 6 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7389756
Default Alt Text
D8261.diff (8 KB)
Attached To
Mode
D8261: Modularize parser for "Closes task X as Y"
Attached
Detach File
Event Timeline
Log In to Comment