diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index f88a94d..f0e1c72 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -15,17 +15,8 @@ jobs: checks: uses: Workiva/gha-dart-oss/.github/workflows/checks.yaml@v0.1.6 - sbom: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: dart-lang/setup-dart@v1 - with: - sdk: 2.19.6 - - uses: anchore/sbom-action@v0 - with: - path: ./ - format: cyclonedx-json + build: + uses: Workiva/gha-dart-oss/.github/workflows/build.yaml@v0.1.6 snapshots: runs-on: ubuntu-latest diff --git a/lib/src/relationship_generator.dart b/lib/src/relationship_generator.dart index d6c612c..c5a8526 100644 --- a/lib/src/relationship_generator.dart +++ b/lib/src/relationship_generator.dart @@ -27,30 +27,42 @@ List? relationshipsFor( // Since mixins do not support inheritance, we only care about // methods that exist on classes - if (node is MethodDeclaration && node.parent is ClassDeclaration) { - final parentNode = node.parent as ClassDeclaration?; + if (element is MethodElement || + element is FieldElement || + element is PropertyAccessorElement) { + final parentNode = node.thisOrAncestorOfType(); final parentElement = parentNode?.declaredElement; // this shouldn't happen, but if the parent element happens to be // null, just fail fast if (parentElement == null) return null; - // retrieve all of the methods and accessors of every parent type that - // has the same name of [node]. These are the elements that this [node] - // are overriding - final referencingElements = parentElement.allSupertypes - .map((type) => [...type.methods, ...type.accessors]) - .expand((type) => type) - .where((type) => type.name == node.name.toString()); - - if (referencingElements.isNotEmpty) { - return referencingElements - .map((type) => Relationship( - symbol: symbolGenerator.symbolFor(type), - isImplementation: true, - isReference: true)) - .toList(); + late final Iterable referencingElements; + if (element is MethodElement) { + referencingElements = parentElement.allSupertypes + .expand((type) => type.methods) + .where((type) => type.name == element.name); + } else if (element is FieldElement) { + referencingElements = parentElement.allSupertypes + .expand((type) => type.accessors) + .map((acc) => acc.variable) + .where((variable) => variable.name == element.name) + .toSet(); // remove any duplicates caused from synthetic getters/setters + } + if (element is PropertyAccessorElement) { + referencingElements = parentElement.allSupertypes + .expand((type) => type.accessors) + .where((acc) => acc.isSetter == element.isSetter) + .where((acc) => acc.isGetter == element.isGetter) + .where((acc) => acc.variable.name == element.variable.name); } + + return referencingElements + .map((type) => Relationship( + symbol: symbolGenerator.symbolFor(type), + isImplementation: true, + isReference: true)) + .toList(); } return null; diff --git a/lib/src/symbol_generator.dart b/lib/src/symbol_generator.dart index 648ef18..76b80c8 100644 --- a/lib/src/symbol_generator.dart +++ b/lib/src/symbol_generator.dart @@ -257,10 +257,18 @@ class SymbolGenerator { if (element is PropertyAccessorElement) { final parentName = element.enclosingElement.name; + + var prefix = ''; + if (element.isGetter) { + prefix = ''; + } else if (element.isSetter) { + prefix = ''; + } + return [ '$namespace/', if (parentName != null) '$parentName#', - '${element.name}.' + '`$prefix${element.variable.name}`.', ].join(); } diff --git a/snapshots/input/basic-project/lib/relationships.dart b/snapshots/input/basic-project/lib/relationships.dart index bd028ee..1ad9923 100644 --- a/snapshots/input/basic-project/lib/relationships.dart +++ b/snapshots/input/basic-project/lib/relationships.dart @@ -1,9 +1,14 @@ abstract class Mammal { - String get hierarchy; + String get someGetter; + set someSetter(String v); + String field = ''; } abstract class Animal extends Mammal { String sound() => 'NOISE!'; + + @override + String field = 'asdf'; } mixin SwimAction { @@ -11,9 +16,15 @@ mixin SwimAction { } class Dog extends Animal with SwimAction { + @override + String field = 'otherVal'; + @override String sound() => 'woof'; @override - String get hierarchy => 'dog.animal.mammal'; + String get someGetter => 'value'; + + @override + set someSetter(String v) {}; } \ No newline at end of file diff --git a/snapshots/output/basic-project/lib/relationships.dart b/snapshots/output/basic-project/lib/relationships.dart index 25ee4e0..dc6a8d9 100755 --- a/snapshots/output/basic-project/lib/relationships.dart +++ b/snapshots/output/basic-project/lib/relationships.dart @@ -1,9 +1,16 @@ abstract class Mammal { // definition scip-dart pub dart_test 1.0.0 lib/`relationships.dart`/ // ^^^^^^ definition scip-dart pub dart_test 1.0.0 lib/`relationships.dart`/Mammal# - String get hierarchy; + String get someGetter; // ^^^^^^ reference scip-dart pub dart:core 2.19.0 dart:core/`string.dart`/String# -// ^^^^^^^^^ definition scip-dart pub dart_test 1.0.0 lib/`relationships.dart`/Mammal#hierarchy. +// ^^^^^^^^^^ definition scip-dart pub dart_test 1.0.0 lib/`relationships.dart`/Mammal#`someGetter`. + set someSetter(String v); +// ^^^^^^^^^^ definition scip-dart pub dart_test 1.0.0 lib/`relationships.dart`/Mammal#`someSetter`. +// ^^^^^^ reference scip-dart pub dart:core 2.19.0 dart:core/`string.dart`/String# +// ^ definition local 0 + String field = ''; +// ^^^^^^ reference scip-dart pub dart:core 2.19.0 dart:core/`string.dart`/String# +// ^^^^^ definition scip-dart pub dart_test 1.0.0 lib/`relationships.dart`/Mammal#field. } abstract class Animal extends Mammal { @@ -13,6 +20,13 @@ String sound() => 'NOISE!'; // ^^^^^^ reference scip-dart pub dart:core 2.19.0 dart:core/`string.dart`/String# // ^^^^^ definition scip-dart pub dart_test 1.0.0 lib/`relationships.dart`/Animal#sound(). + + @override +// ^^^^^^^^ reference scip-dart pub dart:core 2.19.0 dart:core/`annotations.dart`/override. + String field = 'asdf'; +// ^^^^^^ reference scip-dart pub dart:core 2.19.0 dart:core/`string.dart`/String# +// ^^^^^ definition scip-dart pub dart_test 1.0.0 lib/`relationships.dart`/Animal#field. +// relationship scip-dart pub dart_test 1.0.0 lib/`relationships.dart`/Mammal#field. implementation reference } mixin SwimAction { @@ -29,6 +43,14 @@ // relationship scip-dart pub dart_test 1.0.0 lib/`relationships.dart`/SwimAction# implementation // ^^^^^^ reference scip-dart pub dart_test 1.0.0 lib/`relationships.dart`/Animal# // ^^^^^^^^^^ reference scip-dart pub dart_test 1.0.0 lib/`relationships.dart`/SwimAction# + @override +// ^^^^^^^^ reference scip-dart pub dart:core 2.19.0 dart:core/`annotations.dart`/override. + String field = 'otherVal'; +// ^^^^^^ reference scip-dart pub dart:core 2.19.0 dart:core/`string.dart`/String# +// ^^^^^ definition scip-dart pub dart_test 1.0.0 lib/`relationships.dart`/Dog#field. +// relationship scip-dart pub dart_test 1.0.0 lib/`relationships.dart`/Animal#field. implementation reference +// relationship scip-dart pub dart_test 1.0.0 lib/`relationships.dart`/Mammal#field. implementation reference + @override // ^^^^^^^^ reference scip-dart pub dart:core 2.19.0 dart:core/`annotations.dart`/override. String sound() => 'woof'; @@ -38,8 +60,16 @@ @override // ^^^^^^^^ reference scip-dart pub dart:core 2.19.0 dart:core/`annotations.dart`/override. - String get hierarchy => 'dog.animal.mammal'; + String get someGetter => 'value'; // ^^^^^^ reference scip-dart pub dart:core 2.19.0 dart:core/`string.dart`/String# -// ^^^^^^^^^ definition scip-dart pub dart_test 1.0.0 lib/`relationships.dart`/Dog#hierarchy. -// relationship scip-dart pub dart_test 1.0.0 lib/`relationships.dart`/Mammal#hierarchy. implementation reference +// ^^^^^^^^^^ definition scip-dart pub dart_test 1.0.0 lib/`relationships.dart`/Dog#`someGetter`. +// relationship scip-dart pub dart_test 1.0.0 lib/`relationships.dart`/Mammal#`someGetter`. implementation reference + + @override +// ^^^^^^^^ reference scip-dart pub dart:core 2.19.0 dart:core/`annotations.dart`/override. + set someSetter(String v) {}; +// ^^^^^^^^^^ definition scip-dart pub dart_test 1.0.0 lib/`relationships.dart`/Dog#`someSetter`. +// relationship scip-dart pub dart_test 1.0.0 lib/`relationships.dart`/Mammal#`someSetter`. implementation reference +// ^^^^^^ reference scip-dart pub dart:core 2.19.0 dart:core/`string.dart`/String# +// ^ definition local 1 }