Skip to content

Commit

Permalink
Merge pull request #152 from Workiva/fixed_getters_setters_and_field_…
Browse files Browse the repository at this point in the history
…relationships

FEDX-1670: Fixed getters, setters, and field relationships
  • Loading branch information
rmconsole2-wf authored Sep 27, 2024
2 parents 71ad02e + 7de6381 commit 2fec13e
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 36 deletions.
13 changes: 2 additions & 11 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,8 @@ jobs:
checks:
uses: Workiva/gha-dart-oss/.github/workflows/[email protected]

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/[email protected]

snapshots:
runs-on: ubuntu-latest
Expand Down
46 changes: 29 additions & 17 deletions lib/src/relationship_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,30 +27,42 @@ List<Relationship>? 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<ClassDeclaration>();
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<Element> 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;
Expand Down
10 changes: 9 additions & 1 deletion lib/src/symbol_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -257,10 +257,18 @@ class SymbolGenerator {

if (element is PropertyAccessorElement) {
final parentName = element.enclosingElement.name;

var prefix = '';
if (element.isGetter) {
prefix = '<get>';
} else if (element.isSetter) {
prefix = '<set>';
}

return [
'$namespace/',
if (parentName != null) '$parentName#',
'${element.name}.'
'`$prefix${element.variable.name}`.',
].join();
}

Expand Down
15 changes: 13 additions & 2 deletions snapshots/input/basic-project/lib/relationships.dart
Original file line number Diff line number Diff line change
@@ -1,19 +1,30 @@
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 {
void execute() => print('swimming...');
}

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) {};
}
40 changes: 35 additions & 5 deletions snapshots/output/basic-project/lib/relationships.dart
Original file line number Diff line number Diff line change
@@ -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#`<get>someGetter`.
set someSetter(String v);
// ^^^^^^^^^^ definition scip-dart pub dart_test 1.0.0 lib/`relationships.dart`/Mammal#`<set>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 {
Expand All @@ -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 {
Expand All @@ -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';
Expand All @@ -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#`<get>someGetter`.
// relationship scip-dart pub dart_test 1.0.0 lib/`relationships.dart`/Mammal#`<get>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#`<set>someSetter`.
// relationship scip-dart pub dart_test 1.0.0 lib/`relationships.dart`/Mammal#`<set>someSetter`. implementation reference
// ^^^^^^ reference scip-dart pub dart:core 2.19.0 dart:core/`string.dart`/String#
// ^ definition local 1
}

0 comments on commit 2fec13e

Please sign in to comment.