Skip to content

Type inference: Simplify internal representation of type paths #19570

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 26, 2025
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -181,44 +181,25 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
/** Holds if this type path is empty. */
predicate isEmpty() { this = "" }

/** Gets the length of this path, assuming the length is at least 2. */
bindingset[this]
pragma[inline_late]
private int lengthAtLeast2() {
// Same as
// `result = strictcount(this.indexOf(".")) + 1`
// but performs better because it doesn't use an aggregate
result = this.regexpReplaceAll("[0-9]+", "").length() + 1
}

/** Gets the length of this path. */
bindingset[this]
pragma[inline_late]
int length() {
if this.isEmpty()
then result = 0
else
if exists(TypeParameter::decode(this))
then result = 1
else result = this.lengthAtLeast2()
// Same as
// `result = count(this.indexOf("."))`
// but performs better because it doesn't use an aggregate
Comment on lines +189 to +190
Copy link
Preview

Copilot AI May 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment references count(this.indexOf(".")), but the implementation now uses regexpReplaceAll(...).length() to count separators. Consider updating the comment to clearly describe that it counts dots in the string.

Suggested change
// `result = count(this.indexOf("."))`
// but performs better because it doesn't use an aggregate
// Counts the number of dots in the string by removing numeric characters
// using a regular expression and calculating the length of the resulting string.

Copilot uses AI. Check for mistakes.

result = this.regexpReplaceAll("[0-9]+", "").length()
}

/** Gets the path obtained by appending `suffix` onto this path. */
bindingset[this, suffix]
TypePath append(TypePath suffix) {
if this.isEmpty()
then result = suffix
else
if suffix.isEmpty()
then result = this
else (
result = this + "." + suffix and
(
not exists(getTypePathLimit())
or
result.lengthAtLeast2() <= getTypePathLimit()
)
)
result = this + suffix and
(
not exists(getTypePathLimit())
or
result.length() <= getTypePathLimit()
)
}

/**
Expand All @@ -232,16 +213,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {

/** Gets the path obtained by removing `prefix` from this path. */
bindingset[this, prefix]
TypePath stripPrefix(TypePath prefix) {
if prefix.isEmpty()
then result = this
else (
this = prefix and
result.isEmpty()
or
this = prefix + "." + result
)
}
TypePath stripPrefix(TypePath prefix) { this = prefix + result }

/** Holds if this path starts with `tp`, followed by `suffix`. */
bindingset[this]
Expand All @@ -256,7 +228,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
TypePath nil() { result.isEmpty() }

/** Gets the singleton type path `tp`. */
TypePath singleton(TypeParameter tp) { result = TypeParameter::encode(tp) }
TypePath singleton(TypeParameter tp) { result = TypeParameter::encode(tp) + "." }

/**
* Gets the type path obtained by appending the singleton type path `tp`
Expand Down
Loading