Skip to content

Commit

Permalink
Engine: updated ScriptSymbolsMap::GetIndexOfAny()
Browse files Browse the repository at this point in the history
...this fixes couple of edge cases.
  • Loading branch information
ivan-mogilko committed Dec 24, 2024
1 parent 2d0167f commit 3c72bc1
Showing 1 changed file with 27 additions and 17 deletions.
44 changes: 27 additions & 17 deletions Engine/script/systemimports.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,11 @@ uint32_t ScriptSymbolsMap::GetIndexOfAny(const String &name) const
// where "type" is the name of a type, "name" is the name of a function,
// "argnum" is the number of arguments.

const size_t argnum_at = name.FindChar(_appendageSeparator);
const size_t argnum_at = std::min(name.GetLength(), name.FindChar(_appendageSeparator));
const size_t append_end = name.GetLength();
// TODO: optimize this by supporting string views! or compare methods which let compare with a substring of input
const String name_only = name.Left(argnum_at);
const String argnum_only = (argnum_at != UINT32_MAX) ? name.Mid(argnum_at + 1) : String();
const String argnum_only = name.Mid(argnum_at + 1, append_end - argnum_at - 1);

// Scan the range of possible matches, starting with pure name without appendages.
// The match logic is this:
Expand All @@ -75,32 +76,41 @@ uint32_t ScriptSymbolsMap::GetIndexOfAny(const String &name) const
// If base name is not matching, then there's no reason to continue the range
if (try_sym.CompareLeft(name_only, argnum_at) != 0)
break;

// If the symbol is longer, but there's no separator after base name,
// then the symbol has a different, longer base name (e.g. "FindChar" vs "FindCharacter")
if ((try_sym.GetLength() > name_only.GetLength()) && try_sym[name_only.GetLength()] != _appendageSeparator)
continue;
// If the request is without appendage, then choose the first found symbol
// which has at least base name matching (it will be exact match if one exists in symbol map)
if (argnum_at == String::NoIndex)

// Search for appendage separators in the matching symbol
const size_t sym_argnum_at = std::min(try_sym.GetLength(), try_sym.FindChar(_appendageSeparator, argnum_at));
const size_t sym_append_end = try_sym.GetLength();

//---------------------------------------------------------------------
// Check the argnum appendage

// If the symbol does not have any appendages, then:
// - if request does not have any either, that's the exact match;
// - otherwise save it as a best match and continue searching;
if (sym_argnum_at == try_sym.GetLength())
{
if ((try_sym.GetLength() == name_only.GetLength()) ||
_allowMatchExpanded)
{
if (argnum_at == name.GetLength())
return it->second;
}
break; // exact base-name match would be first in order, so no reason to continue
}

// Second - compare argnum appendage
// If the request has appendage, but the symbol does not, then save it as a best match and continue
if (try_sym.GetLength() == name_only.GetLength())
{
best_match = it->second;
continue;
}

// If the request is without argnum, then optionally choose the first found symbol
// which has at least base name matching
if (argnum_at == name.GetLength())
{
if (_allowMatchExpanded)
return it->second;
break; // exact base-name match would be first in order, so no reason to continue
}

// Compare argnum appendage, and skip on failure
if (try_sym.CompareMid(argnum_only, argnum_at + 1) != 0)
if ((sym_append_end != append_end) || try_sym.CompareMid(argnum_only, argnum_at + 1) != 0)
continue;

// Matched whole appendage, found exact match
Expand Down

0 comments on commit 3c72bc1

Please sign in to comment.