-
Notifications
You must be signed in to change notification settings - Fork 110
Add spanForElement, for nicer debugging messages.
#206
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
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 |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | ||
| // for details. All rights reserved. Use of this source code is governed by a | ||
| // BSD-style license that can be found in the LICENSE file. | ||
|
|
||
| import 'package:analyzer/dart/element/element.dart'; | ||
| import 'package:source_span/source_span.dart'; | ||
|
|
||
| import 'utils.dart'; | ||
|
|
||
| /// Returns a source span that spans the location where [element] is defined. | ||
| /// | ||
| /// May be used to emit user-friendly warning and error messages: | ||
| /// ```dart | ||
| /// void invalidClass(ClassElement class) { | ||
| /// log.warning(spanForElement.message('Cannot implement "Secret"')); | ||
| /// } | ||
| /// ``` | ||
| /// | ||
| /// Not all results from the analyzer API may return source information as part | ||
| /// of the element, so [file] may need to be manually provided in those cases. | ||
| SourceSpan spanForElement(Element element, [SourceFile file]) { | ||
| final url = assetToPackageUrl(element.source.uri); | ||
| if (file == null) { | ||
| final contents = element?.source?.contents; | ||
| if (contents == null) { | ||
| return new SourceSpan( | ||
| new SourceLocation( | ||
| element.nameOffset, | ||
| sourceUrl: url, | ||
| ), | ||
| new SourceLocation( | ||
| element.nameOffset + element.nameLength, | ||
| sourceUrl: url, | ||
| ), | ||
| element.name, | ||
| ); | ||
| } | ||
| file = new SourceFile.fromString(contents.data, url: url); | ||
| } | ||
| return file.span(element.nameOffset, element.nameOffset + element.nameLength); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -105,13 +105,13 @@ Uri normalizeDartUrl(Uri url) => url.pathSegments.isNotEmpty | |
| ? url.replace(pathSegments: url.pathSegments.take(1)) | ||
| : url; | ||
|
|
||
| /// Returns a `package:` URL into a `asset:` URL. | ||
| /// Returns a `package:` URL converted to a `asset:` URL. | ||
| /// | ||
| /// This makes internal comparison logic much easier, but still allows users | ||
| /// to define assets in terms of `package:`, which is something that makes more | ||
| /// sense to most. | ||
| /// | ||
| /// For example this transforms `package:source_gen/source_gen.dart` into: | ||
| /// For example, this transforms `package:source_gen/source_gen.dart` into: | ||
| /// `asset:source_gen/lib/source_gen.dart`. | ||
| Uri packageToAssetUrl(Uri url) => url.scheme == 'package' | ||
| ? url.replace( | ||
|
|
@@ -122,6 +122,24 @@ Uri packageToAssetUrl(Uri url) => url.scheme == 'package' | |
| ..addAll(url.pathSegments.skip(1))) | ||
| : url; | ||
|
|
||
| /// Returns a `asset:` URL converted to a `package:` URL. | ||
|
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. Where is the Might be nice to clarify this... 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. Your wish is my command, |
||
| /// | ||
| /// For example, this transformers `asset:source_gen/lib/source_gen.dart' into: | ||
| /// `package:source_gen/source_gen.dart`. Asset URLs that aren't pointing to a | ||
| /// file in the 'lib' folder are not modified. | ||
| /// | ||
| /// Asset URLs come from `package:build`, as they are able to describe URLs that | ||
| /// are not describable using `package:...`, such as files in the `bin`, `tool`, | ||
| /// `web`, or even root directory of a package - `asset:some_lib/web/main.dart`. | ||
| Uri assetToPackageUrl(Uri url) => url.scheme == 'asset' && | ||
| url.pathSegments.length >= 1 && | ||
| url.pathSegments[1] == 'lib' | ||
| ? url.replace( | ||
| scheme: 'package', | ||
| pathSegments: [url.pathSegments.first] | ||
| ..addAll(url.pathSegments.skip(2))) | ||
| : url; | ||
|
|
||
| /// Returns all of the declarations in [unit], including [unit] as the first | ||
| /// item. | ||
| Iterable<Element> getElementsFromLibraryElement(LibraryElement unit) sync* { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | ||
| // for details. All rights reserved. Use of this source code is governed by a | ||
| // BSD-style license that can be found in the LICENSE file. | ||
|
|
||
| import 'package:analyzer/dart/element/element.dart'; | ||
| import 'package:build/build.dart'; | ||
| import 'package:build_test/build_test.dart'; | ||
| import 'package:source_gen/source_gen.dart'; | ||
| import 'package:test/test.dart'; | ||
|
|
||
| void main() { | ||
| LibraryElement library; | ||
|
|
||
| setUpAll(() async { | ||
| final resolver = await resolveSource(r''' | ||
| library test_lib; | ||
| abstract class Example implements List {} | ||
| ''', inputId: new AssetId('test_lib', 'lib/test_lib.dart')); | ||
| library = resolver.getLibraryByName('test_lib'); | ||
| }); | ||
|
|
||
| test('should highlight the use of "class Example"', () { | ||
| expect( | ||
| spanForElement(library.getType('Example')).message('Here it is'), | ||
|
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. That's pretty cool! |
||
| '' | ||
| 'line 3, column 22 of package:test_lib/test_lib.dart: Here it is\n' | ||
| ' abstract class Example implements List {}\n' | ||
| ' ^^^^^^^'); | ||
| }); | ||
| } | ||
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.
Missing explicit dependency on
source_spanhere...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.
Well, not here – in pubspec
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.
Your wish is my command,