-
Notifications
You must be signed in to change notification settings - Fork 2
FEDX-1213: Localized element selection logic to the SymbolGenerator #128
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
Changes from all commits
0575e79
c37dc02
72ff06f
4f2cc40
ab47f1d
ec61682
64fd45f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
import 'package:analyzer/dart/ast/ast.dart'; | ||
import 'package:analyzer/dart/element/element.dart'; | ||
import 'package:pubspec_parse/pubspec_parse.dart'; | ||
import 'package:package_config/package_config.dart'; | ||
|
@@ -22,6 +23,75 @@ class SymbolGenerator { | |
|
||
SymbolGenerator(this._packageConfig, this._pubspec); | ||
|
||
/// For a given [AstNode], returns the correlating [Element] type | ||
/// that should be used to generate the symbol | ||
Element? elementFor(AstNode node) { | ||
if (node is Declaration) { | ||
return node.declaredElement; | ||
} else if (node is NormalFormalParameter) { | ||
// if this parameter is a child of a GenericFunctionType (can be a | ||
// typedef, or a function as a parameter), we don't want to index it | ||
// as a definition (nothing is defined, just referenced). Return false | ||
// and let the [_visitSimpleIdentifier] declare the reference | ||
final parentParameter = | ||
node.parent?.thisOrAncestorOfType<GenericFunctionType>(); | ||
if (parentParameter != null) return null; | ||
|
||
var element = node.declaredElement; | ||
if (element == null) return null; | ||
|
||
return element; | ||
} else if (node is SimpleIdentifier) { | ||
var element = node.staticElement; | ||
|
||
// Both `.loadLibrary()`, and `.call()` are synthetic functions that | ||
// have no definition. These should therefore should not be indexed. | ||
if (element is FunctionElement && element.isSynthetic) { | ||
if ([ | ||
FunctionElement.LOAD_LIBRARY_NAME, | ||
FunctionElement.CALL_METHOD_NAME, | ||
].contains(element.name)) return null; | ||
} | ||
|
||
// [element] for assignment fields is null. If the parent node | ||
// is a `CompoundAssignmentExpression`, we know this node is referring | ||
// to an assignment line. In that case, use the read/write element attached | ||
// to this node instead of the [node]'s element | ||
if (element == null) { | ||
final assignmentExpr = | ||
node.thisOrAncestorOfType<CompoundAssignmentExpression>(); | ||
if (assignmentExpr == null) return null; | ||
|
||
element = assignmentExpr.readElement ?? assignmentExpr.writeElement; | ||
} | ||
|
||
// When the identifier is a field, the analyzer creates synthetic getters/ | ||
// setters for it. We need to get the backing field. | ||
if (element?.isSynthetic == true && element is PropertyAccessorElement) { | ||
// The values field on enums is synthetic, and has no explicit definition like | ||
// other fields do. Skip indexing for this case. | ||
if (element.enclosingElement is EnumElement && | ||
element.name == 'values') { | ||
return null; | ||
} | ||
Comment on lines
+71
to
+76
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the part that closes #37 |
||
|
||
element = element.variable; | ||
} | ||
|
||
// element is null if there's nothing really to do for this node. Example: `void` | ||
// TODO: One weird issue found: named parameters of external symbols were element.source | ||
// EX: `color(path, front: Styles.YELLOW);` where `color` comes from the chalk-dart package | ||
if (element?.source == null) return null; | ||
|
||
return element; | ||
} | ||
|
||
display('WARN: Received unknown ast node type in elementFor: ' | ||
'${node.runtimeType} ($node). Skipping'); | ||
|
||
return null; | ||
} | ||
|
||
/// For a given `Element` returns the scip symbol form. | ||
/// | ||
/// Returns [null] if symbol cannot be created for provided element | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,6 +43,10 @@ | |
// ^^^^^^ reference scip-dart pub dart_test 1.0.0 lib/`more.dart`/Animal# | ||
// ^^^^ reference scip-dart pub dart_test 1.0.0 lib/`more.dart`/Animal#name. | ||
// ^^^^ reference scip-dart pub dart_test 1.0.0 lib/`more.dart`/Animal#type. | ||
// ^^^^ definition scip-dart pub dart_test 1.0.0 lib/`more.dart`/Animal#`<constructor>`().(type) | ||
print(AnimalType.values); | ||
// ^^^^^ reference scip-dart pub dart:core 2.19.0 dart:core/`print.dart`/print(). | ||
// ^^^^^^^^^^ reference scip-dart pub dart_test 1.0.0 lib/`more.dart`/AnimalType# | ||
Comment on lines
+47
to
+49
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This validates the case in #37, don't index |
||
switch (type) { | ||
// ^^^^ reference scip-dart pub dart_test 1.0.0 lib/`more.dart`/Animal#type. | ||
case AnimalType.cat: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,10 +23,13 @@ | |
// ^^^^ reference local 0 | ||
required this.value, | ||
// ^^^^^ reference scip-dart pub dart_test 1.0.0 lib/`other.dart`/Foo#value. | ||
// ^^^^^ definition scip-dart pub dart_test 1.0.0 lib/`other.dart`/Foo#`<constructor>`().(value) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. named parameters are indexed as both references and definitions, this is due to the case mentioned in #120, where they are goto'd from a declaration side of things |
||
required this.value2, | ||
// ^^^^^^ reference scip-dart pub dart_test 1.0.0 lib/`other.dart`/Foo#value2. | ||
// ^^^^^^ definition scip-dart pub dart_test 1.0.0 lib/`other.dart`/Foo#`<constructor>`().(value2) | ||
this.value3, | ||
// ^^^^^^ reference scip-dart pub dart_test 1.0.0 lib/`other.dart`/Foo#value3. | ||
// ^^^^^^ definition scip-dart pub dart_test 1.0.0 lib/`other.dart`/Foo#`<constructor>`().(value3) | ||
}) { | ||
print(_far); | ||
// ^^^^^ reference scip-dart pub dart:core 2.19.0 dart:core/`print.dart`/print(). | ||
|
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.
This fixes #120