-
Notifications
You must be signed in to change notification settings - Fork 1.8k
language reference entry for non-extending subtypes #6592
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this functionally identical to extending Foo
's base types and writing this instanceof Foo
in Bar
's charpred? If so, that might be useful to mention.
Co-authored-by: Chris Smowton <smowton@github.com>
It isn't quite the same. To be specific, it goes beyond just adding it to the charpred in two ways:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think being clearer about which things care about extend
s and which are instanceof
earlier in this document may help.
I think the comparison to instanceof
would actually be good saying something like
"Foo instanceof Baris reoughly equivalent to saying
this instanceof Barin the charpred. The main differences are that you can call methods on
Barvia
super` and you can get better optimisation.
class Bar extends Interface instanceof Foo { | ||
override string foo() { result = "bar" } | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again I think the overlapping instanceof
/extends
hierarchy is just confusing here. I would have a simpler example like the following:
class Interface instanceof int {
Interface() { this in [1 .. 100] }
string foo() { result = "" }
}
class Foo extends int {
Foo() { this in [1 .. 10] }
string foo() { result = "foo" }
}
class Bar extends Interface instanceof Foo {
override string foo() { result = "bar" }
}
Here we don't need to understand the subtle differences between rootdefs and where exactly overriding happens.
Also your current example seems wrong select any(Foo b).foo()
should call Interface::foo
which should include "bar"
as Bar::foo
overrides Interface::foo
. This seems an implementation bug.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have opened an issue (https://github.com/github/codeql-coreql-team/issues/1513) for the implementation bug.
I attempted to take your example, but the toString
methods became messy. Does the following make sense to you (commit 9)?
class Interface extends int {
Interface() { this in [1 .. 10] }
string foo() { result = "" }
}
class Foo extends int {
Foo() { this in [1 .. 5] }
string foo() { result = "foo" }
}
class Bar extends Interface instanceof Foo {
override string foo() { result = "bar" }
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The implementation bug should be fixed now: https://github.com/github/semmle-code/pull/40188
Thank you for the detailed suggestions @alexet !
I have added a sentence like this in commit 8. |
Co-authored-by: Nick Rolfe <nickrolfe@github.com>
fixes https://github.com/github/codeql-coreql-team/issues/1494