Rust: Crate graph extraction workarounds

This commit is contained in:
Tom Hvitved
2025-04-24 11:03:59 +02:00
parent 7106475033
commit 97532525d8
2 changed files with 61 additions and 13 deletions

View File

@@ -323,7 +323,16 @@ abstract private class AssocItemNode extends ItemNode, AssocItem {
private class ConstItemNode extends AssocItemNode instanceof Const {
override string getName() { result = Const.super.getName().getText() }
override predicate hasImplementation() { super.hasBody() }
override predicate hasImplementation() {
super.hasBody()
or
// for trait items from library code, we do not currently know if they
// have default implementations or not, so we assume they do
exists(TraitItemNode t |
this = t.getAnAssocItem() and
not this.fromSource()
)
}
override Namespace getNamespace() { result.isValue() }
@@ -359,7 +368,16 @@ private class VariantItemNode extends ItemNode instanceof Variant {
class FunctionItemNode extends AssocItemNode instanceof Function {
override string getName() { result = Function.super.getName().getText() }
override predicate hasImplementation() { super.hasBody() }
override predicate hasImplementation() {
super.hasBody()
or
// for trait items from library code, we do not currently know if they
// have default implementations or not, so we assume they do
exists(TraitItemNode t |
this = t.getAnAssocItem() and
not this.fromSource()
)
}
override Namespace getNamespace() { result.isValue() }
@@ -862,6 +880,12 @@ class RelevantPath extends Path {
this.getQualifier().(RelevantPath).isCratePath("$crate", _) and
this.getText() = name
}
// TODO: Remove once the crate graph extractor generates publicly visible paths
predicate requiresExtractorWorkaround() {
not this.fromSource() and
this = any(RelevantPath p).getQualifier()
}
}
private predicate isModule(ItemNode m) { m instanceof Module }
@@ -1029,6 +1053,7 @@ pragma[nomagic]
private ItemNode resolvePathPrivate(
RelevantPath path, ModuleLikeNode itemParent, ModuleLikeNode pathParent
) {
not path.requiresExtractorWorkaround() and
result = resolvePath1(path) and
itemParent = result.getImmediateParentModule() and
not result.isPublic() and
@@ -1062,7 +1087,11 @@ private ModuleLikeNode getAPrivateVisibleModule(ModuleLikeNode itemParent) {
cached
ItemNode resolvePath(RelevantPath path) {
result = resolvePath1(path) and
result.isPublic()
(
result.isPublic()
or
path.requiresExtractorWorkaround()
)
or
exists(ModuleLikeNode itemParent, ModuleLikeNode pathParent |
result = resolvePathPrivate(path, itemParent, pathParent) and

View File

@@ -29,7 +29,26 @@ newtype TType =
abstract class Type extends TType {
/** Gets the method `name` belonging to this type, if any. */
pragma[nomagic]
abstract Function getMethod(string name);
final Function getMethod(string name) {
result = this.getAMethod(name) and
(
// when a method exists in both source code and in library code, it is because
// we also extracted the source code as library code, and hence we only want
// the method from source code
result.fromSource()
or
not this.getAMethod(name).fromSource()
)
}
/**
* Gets a method `name` belonging to this type, if any.
*
* Multiple methods may exist with the same name when it exists in both
* source code and in library code.
*/
pragma[nomagic]
abstract Function getAMethod(string name);
/** Gets the struct field `name` belonging to this type, if any. */
pragma[nomagic]
@@ -74,7 +93,7 @@ abstract class Type extends TType {
abstract private class StructOrEnumType extends Type {
abstract ItemNode asItemNode();
final override Function getMethod(string name) {
final override Function getAMethod(string name) {
result = this.asItemNode().getASuccessor(name) and
exists(ImplOrTraitItemNode impl | result = impl.getAnAssocItem() |
impl instanceof Trait
@@ -138,7 +157,7 @@ class TraitType extends Type, TTrait {
TraitType() { this = TTrait(trait) }
override Function getMethod(string name) { result = trait.(ItemNode).getASuccessor(name) }
override Function getAMethod(string name) { result = trait.(ItemNode).getASuccessor(name) }
override StructField getStructField(string name) { none() }
@@ -220,7 +239,7 @@ class ImplType extends Type, TImpl {
ImplType() { this = TImpl(impl) }
override Function getMethod(string name) { result = impl.(ItemNode).getASuccessor(name) }
override Function getAMethod(string name) { result = impl.(ItemNode).getASuccessor(name) }
override StructField getStructField(string name) { none() }
@@ -247,7 +266,7 @@ class ImplType extends Type, TImpl {
class ArrayType extends Type, TArrayType {
ArrayType() { this = TArrayType() }
override Function getMethod(string name) { none() }
override Function getAMethod(string name) { none() }
override StructField getStructField(string name) { none() }
@@ -273,7 +292,7 @@ class ArrayType extends Type, TArrayType {
class RefType extends Type, TRefType {
RefType() { this = TRefType() }
override Function getMethod(string name) { none() }
override Function getAMethod(string name) { none() }
override StructField getStructField(string name) { none() }
@@ -318,7 +337,7 @@ class TypeParamTypeParameter extends TypeParameter, TTypeParamTypeParameter {
TypeParam getTypeParam() { result = typeParam }
override Function getMethod(string name) {
override Function getAMethod(string name) {
// NOTE: If the type parameter has trait bounds, then this finds methods
// on the bounding traits.
result = typeParam.(ItemNode).getASuccessor(name)
@@ -377,7 +396,7 @@ class AssociatedTypeTypeParameter extends TypeParameter, TAssociatedTypeTypePara
int getIndex() { traitAliasIndex(_, result, typeAlias) }
override Function getMethod(string name) { none() }
override Function getAMethod(string name) { none() }
override string toString() { result = typeAlias.getName().getText() }
@@ -388,7 +407,7 @@ class AssociatedTypeTypeParameter extends TypeParameter, TAssociatedTypeTypePara
/** An implicit reference type parameter. */
class RefTypeParameter extends TypeParameter, TRefTypeParameter {
override Function getMethod(string name) { none() }
override Function getAMethod(string name) { none() }
override string toString() { result = "&T" }
@@ -411,7 +430,7 @@ class SelfTypeParameter extends TypeParameter, TSelfTypeParameter {
override TypeMention getABaseTypeMention() { result = trait }
override Function getMethod(string name) {
override Function getAMethod(string name) {
// The `Self` type parameter is an implementation of the trait, so it has
// all the trait's methods.
result = trait.(ItemNode).getASuccessor(name)