Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/lib.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ declare namespace __String {

function localeCompare(this: string, compareString: string, locale?: string): int;

function match(this: string, expr: RegExp): string[];
function match(this: string, expr: RegExp): string[] | null;

@borrows("this", "expr")
function matchAll(this: string, expr: RegExp): Iterator<string[]>;
Expand Down Expand Up @@ -399,7 +399,7 @@ declare class String {

localeCompare(this: string, compareString: string, locale?: string): int;

match(this: string, expr: RegExp): string[];
match(this: string, expr: RegExp): string[] | null;

@borrows("this", "expr")
matchAll(this: string, expr: RegExp): Iterator<string[]>;
Expand Down
14 changes: 8 additions & 6 deletions src/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
/// <reference path="core/core.ts" />
/// <reference path="generics/lib.generics.ts" />

// @strict-null false

export function parseInt(val: string, radix = 10) {
return strtol(val, null, radix);
}
Expand Down Expand Up @@ -948,13 +946,15 @@ namespace __String {
return result;
}

export function match(this: string, expr: RegExp): string[] {
export function match(this: string, expr: RegExp): string[] | null {
if (!expr.global)
{
const result = expr.exec(this);
if (result != null)
{
return [...result];
// -mm=own: into a local first, which the return then moves (as matchAll's yield does)
const groups: string[] = [...result];
return groups;
}

return null;
Expand All @@ -976,7 +976,9 @@ namespace __String {
break;
}

return results;
// an empty array when nothing matched, not JavaScript's null: a global match can always be
// walked or counted without a check
return results;
}

@borrows("this", "expr")
Expand Down Expand Up @@ -1500,7 +1502,7 @@ export class String {
return this.value.localeCompare(compareString, locale);
}

public match(expr: RegExp): string[] {
public match(expr: RegExp): string[] | null {
return this.value.match(expr);
}

Expand Down
6 changes: 3 additions & 3 deletions src/native/lib.native.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
@nodrops declare function time(destTime: Reference<long>);

// String
@nodrops declare function strtol(str: string, end: Reference<string>, base: int): int;
@nodrops declare function strtod(str: string, end: Reference<string>): double;
@nodrops declare function strtol(str: string, end: Reference<string> | null, base: int): int;
@nodrops declare function strtod(str: string, end: Reference<string> | null): double;
@nodrops declare function strncmp(str: string, other: string, count: index): int;
// a pointer into `str`, not a string of its own: a `string` result from C is copied
@nodrops declare function strstr(str: string, other: string): Opaque;
Expand Down Expand Up @@ -111,7 +111,7 @@ declare function GC_gcollect(): void;

// regex
@nodrops declare function regexp_test(expr: string, flags: string, s: string): int;
@nodrops declare function regexp_exec(expr: string, flags: string, s: string, cm: Opaque): Opaque;
@nodrops declare function regexp_exec(expr: string, flags: string, s: string, cm: Opaque | null): Opaque | null;
@nodrops declare function regexp_match_results_size(cm: Opaque): index;
@nodrops declare function regexp_match_results_prefix_length(cm: Opaque): index;
@nodrops declare function regexp_match_results_suffix_position(cm: Opaque): index;
Expand Down
21 changes: 17 additions & 4 deletions tests/string_match.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
const paragraph = 'The quick brown fox jumps over the lazy dog. It barked.';
const regex = /[A-Z]/g;
// match gives string[] | null: null when a pattern without the g flag does not match
const found = paragraph.match(regex);

assert(found.length == 2);
assert(<string>found == "T,I");
assert(found != null);
if (found != null) {
assert(found.length == 2);
assert(<string>found == "T,I");

console.log(found);
// Expected output: Array ["T", "I"]
console.log(found);
// Expected output: Array ["T", "I"]
}

assert(paragraph.match(/[0-9]/) == null, "no match is null");

// with the g flag no match is an empty array (JavaScript gives null there too)
const none = paragraph.match(/[0-9]/g);
assert(none != null, "a global match is never null");
if (none != null) {
assert(none.length == 0, "and is empty when nothing matched");
}

console.log("ALL DONE");
16 changes: 13 additions & 3 deletions tests/string_match_lastIndex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ function main() {
assert(re.lastIndex == 1, "test moved lastIndex");

const digits = "1a2b3".match(re);
assert(<string>digits == "1,2,3", "match starts at the beginning");
assert(digits != null, "match finds the digits");
if (digits != null) {
assert(<string>digits == "1,2,3", "match starts at the beginning");
}

assert(re.lastIndex == 0, "match leaves lastIndex at 0");

assert(re.exec("1a2b3") != null, "exec finds the first digit");
Expand All @@ -19,10 +23,16 @@ function main() {

// empty matches
const empties = "abc".match(/x*/g);
assert(empties.length == 4, "an empty match at every position");
assert(empties != null, "empty matches are matches");
if (empties != null) {
assert(empties.length == 4, "an empty match at every position");
}

const words = "ab cd".match(/\w*/g);
assert(<string>words == "ab,,cd,", "empty matches between the words");
assert(words != null, "words and the empty matches between them");
if (words != null) {
assert(<string>words == "ab,,cd,", "empty matches between the words");
}

const emptyAll = [..."ab".matchAll(/x*/g)];
assert(emptyAll.length == 3, "matchAll: an empty match at every position");
Expand Down
Loading