Improve inlining warning messages. Added index_of_char_from.

This commit is contained in:
Christoffer Lerno
2024-06-09 14:38:57 +02:00
parent 5a6443060e
commit 4fc1e39fa2
3 changed files with 111 additions and 7 deletions

View File

@@ -31,6 +31,11 @@ fault NumberConversion
FLOAT_OUT_OF_RANGE, FLOAT_OUT_OF_RANGE,
} }
/**
* Return a temporary String created using the formatting function.
*
* @param [in] fmt `The formatting string`
**/
macro String tformat(String fmt, ...) macro String tformat(String fmt, ...)
{ {
DString str = dstring::temp_with_capacity(fmt.len + $vacount * 8); DString str = dstring::temp_with_capacity(fmt.len + $vacount * 8);
@@ -38,12 +43,24 @@ macro String tformat(String fmt, ...)
return str.str_view(); return str.str_view();
} }
/**
* Return a temporary ZString created using the formatting function.
*
* @param [in] fmt `The formatting string`
**/
macro ZString tformat_zstr(String fmt, ...) macro ZString tformat_zstr(String fmt, ...)
{ {
DString str = dstring::temp_with_capacity(fmt.len + $vacount * 8); DString str = dstring::temp_with_capacity(fmt.len + $vacount * 8);
str.appendf(fmt, $vasplat()); str.appendf(fmt, $vasplat());
return str.zstr_view(); return str.zstr_view();
} }
/**
* Return a new String created using the formatting function.
*
* @param [in] fmt `The formatting string`
* @param [inout] allocator `The allocator to use`
**/
macro String new_format(String fmt, ..., Allocator allocator = allocator::heap()) macro String new_format(String fmt, ..., Allocator allocator = allocator::heap())
{ {
@pool(allocator) @pool(allocator)
@@ -54,6 +71,12 @@ macro String new_format(String fmt, ..., Allocator allocator = allocator::heap()
}; };
} }
/**
* Return a new ZString created using the formatting function.
*
* @param [in] fmt `The formatting string`
* @param [inout] allocator `The allocator to use`
**/
macro ZString new_format_zstr(String fmt, ..., Allocator allocator = allocator::heap()) macro ZString new_format_zstr(String fmt, ..., Allocator allocator = allocator::heap())
{ {
@pool(allocator) @pool(allocator)
@@ -64,6 +87,14 @@ macro ZString new_format_zstr(String fmt, ..., Allocator allocator = allocator::
}; };
} }
/**
* Check if a character is in a set.
*
* @param c `the character to check`
* @param [in] set `The formatting string`
* @pure
* @return `True if a character is in the set`
**/
macro bool char_in_set(char c, String set) macro bool char_in_set(char c, String set)
{ {
foreach (ch : set) if (ch == c) return true; foreach (ch : set) if (ch == c) return true;
@@ -96,8 +127,12 @@ fn String join_new(String[] s, String joiner, Allocator allocator = allocator::h
} }
/** /**
* @param [in] string * Remove characters from the front and end of a string.
* @param [in] to_trim *
* @param [in] string `The string to trim`
* @param [in] to_trim `The set of characters to trim, defaults to whitespace`
* @pure
* @return `a substring of the string passed in`
**/ **/
fn String String.trim(string, String to_trim = "\t\n\r ") fn String String.trim(string, String to_trim = "\t\n\r ")
{ {
@@ -111,8 +146,12 @@ fn String String.trim(string, String to_trim = "\t\n\r ")
} }
/** /**
* Check if the String starts with the needle.
*
* @param [in] string * @param [in] string
* @param [in] needle * @param [in] needle
* @pure
* @return `'true' if the string starts with the needle`
**/ **/
fn bool String.starts_with(string, String needle) fn bool String.starts_with(string, String needle)
{ {
@@ -122,8 +161,12 @@ fn bool String.starts_with(string, String needle)
} }
/** /**
* Check if the String ends with the needle.
*
* @param [in] string * @param [in] string
* @param [in] needle * @param [in] needle
* @pure
* @return `'true' if the string ends with the needle`
**/ **/
fn bool String.ends_with(string, String needle) fn bool String.ends_with(string, String needle)
{ {
@@ -137,6 +180,8 @@ fn bool String.ends_with(string, String needle)
* *
* @param [in] string * @param [in] string
* @param [in] needle * @param [in] needle
* @pure
* @return `the substring with the prefix removed`
**/ **/
fn String String.strip(string, String needle) fn String String.strip(string, String needle)
{ {
@@ -149,6 +194,8 @@ fn String String.strip(string, String needle)
* *
* @param [in] string * @param [in] string
* @param [in] needle * @param [in] needle
* @pure
* @return `the substring with the suffix removed`
**/ **/
fn String String.strip_end(string, String needle) fn String String.strip_end(string, String needle)
{ {
@@ -211,6 +258,14 @@ fn String[] String.tsplit(s, String needle, usz max = 0)
return s.split(needle, max, allocator::temp()) @inline; return s.split(needle, max, allocator::temp()) @inline;
} }
/**
* Check if a substring is found in the string.
* @param [in] s
* @param [in] needle "The string to look for."
* @pure
* @return "true if the string contains the substring, false otherwise"
**/
fn bool String.contains(s, String needle) fn bool String.contains(s, String needle)
{ {
return @ok(s.index_of(needle)); return @ok(s.index_of(needle));
@@ -220,6 +275,7 @@ fn bool String.contains(s, String needle)
* Find the index of the first incidence of a string. * Find the index of the first incidence of a string.
* *
* @param [in] s * @param [in] s
* @param needle "The character to look for"
* @pure * @pure
* @ensure return < s.len * @ensure return < s.len
* @return "the index of the needle" * @return "the index of the needle"
@@ -235,9 +291,32 @@ fn usz! String.index_of_char(s, char needle)
} }
/** /**
* Find the index of the first incidence of a string. * Find the index of the first incidence of a character.
* *
* @param [in] s * @param [in] s
* @param needle "The character to look for"
* @param start_index "The index to start with, may exceed max index."
* @pure
* @ensure return < s.len
* @return "the index of the needle"
* @return! SearchResult.MISSING "if the needle cannot be found starting from the start_index"
**/
fn usz! String.index_of_char_from(s, char needle, usz start_index)
{
usz len = s.len;
if (len <= start_index) return SearchResult.MISSING?;
for (usz i = start_index; i < len; i++)
{
if (s[i] == needle) return i;
}
return SearchResult.MISSING?;
}
/**
* Find the index of the first incidence of a character starting from the end.
*
* @param [in] s
* @param needle "the character to find"
* @pure * @pure
* @ensure return < s.len * @ensure return < s.len
* @return "the index of the needle" * @return "the index of the needle"
@@ -430,9 +509,15 @@ fn Char32[]! String.to_temp_utf32(s)
return s.to_new_utf32(allocator::temp()); return s.to_new_utf32(allocator::temp());
} }
/**
* Convert a string to ASCII lower case.
*
* @param [inout] s
* @pure
**/
fn void String.convert_ascii_to_lower(s) fn void String.convert_ascii_to_lower(s)
{ {
foreach (&c : s) if (c.is_upper()) *c += 'a' - 'A'; foreach (&c : s) if (c.is_upper() @pure) *c += 'a' - 'A';
} }
fn String String.new_ascii_to_lower(s, Allocator allocator = allocator::heap()) fn String String.new_ascii_to_lower(s, Allocator allocator = allocator::heap())
@@ -447,11 +532,25 @@ fn String String.temp_ascii_to_lower(s, Allocator allocator = allocator::heap())
return s.new_ascii_to_lower(allocator::temp()); return s.new_ascii_to_lower(allocator::temp());
} }
/**
* Convert a string to ASCII upper case.
*
* @param [inout] s
* @pure
**/
fn void String.convert_ascii_to_upper(s) fn void String.convert_ascii_to_upper(s)
{ {
foreach (&c : s) if (c.is_lower()) *c -= 'a' - 'A'; foreach (&c : s) if (c.is_lower() @pure) *c -= 'a' - 'A';
} }
/**
* Returns a string converted to ASCII upper case.
*
* @param [in] s
* @param [inout] allocator
*
* @return `a new String converted to ASCII upper case.`
**/
fn String String.new_ascii_to_upper(s, Allocator allocator = allocator::heap()) fn String String.new_ascii_to_upper(s, Allocator allocator = allocator::heap())
{ {
String copy = s.copy(allocator); String copy = s.copy(allocator);
@@ -464,6 +563,10 @@ fn StringIterator String.iterator(s)
return { s, 0 }; return { s, 0 };
} }
/**
* @param [in] s
* @return `a temporary String converted to ASCII upper case.`
**/
fn String String.temp_ascii_to_upper(s) fn String String.temp_ascii_to_upper(s)
{ {
return s.new_ascii_to_upper(allocator::temp()); return s.new_ascii_to_upper(allocator::temp());

View File

@@ -32,6 +32,7 @@
- Bug when assigning an optional from an optional. - Bug when assigning an optional from an optional.
- Lambdas were not type checked thoroughly #1185. - Lambdas were not type checked thoroughly #1185.
- Fix problems using reflection on interface types #1203. - Fix problems using reflection on interface types #1203.
- `@param` with unnamed macro varargs could crash the compiler.
### Stdlib changes ### Stdlib changes
- "init_new/init_temp" removed. - "init_new/init_temp" removed.

View File

@@ -2704,13 +2704,13 @@ static inline bool sema_analyse_doc_header(SemaContext *context, AstId doc,
VECEACH(params, j) VECEACH(params, j)
{ {
param = params[j]; param = params[j];
if (param->name == param_name) goto NEXT; if (param && param->name == param_name) goto NEXT;
} }
VECEACH(extra_params, j) VECEACH(extra_params, j)
{ {
assert(extra_params); assert(extra_params);
param = extra_params[j]; param = extra_params[j];
if (param->name == param_name) goto NEXT; if (param && param->name == param_name) goto NEXT;
} }
RETURN_SEMA_ERROR(&directive->contract_stmt.param, "There is no parameter '%s', did you misspell it?", param_name); RETURN_SEMA_ERROR(&directive->contract_stmt.param, "There is no parameter '%s', did you misspell it?", param_name);
NEXT:; NEXT:;