-
Notifications
You must be signed in to change notification settings - Fork 110
Add TypeChecker class. #153
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
Conversation
|
I just saw this PR. This might also close #155 (which I just opened). I'll have to check... |
|
@matanlurey I like...but! I noticed when trying to convert the JsonSerialiableGenerator to it it blows up w/ the If you could – check it out. Or I'll do a follow-up. It's certainly better than the hacks I have in place to detect DateTime, Iterable, and List |
|
@kevmoo Let me try converting your generator as a test case then. |
|
Look at this crazy
https://github.com/dart-lang/source_gen/blob/master/lib/generators/json_serializable_generator.dart#L318
…On Sun, Jun 18, 2017 at 5:32 PM, Matan Lurey ***@***.***> wrote:
@kevmoo <https://github.com/kevmoo> Let me try converting your generator
as a test case then.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#153 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AABCihtaOiZkCMeliEoVcAZGBd7zGu_kks5sFcG4gaJpZM4N9n6Y>
.
|
|
@kevmoo Just updated, and added String _fieldToJsonMapKey(String fieldName, FieldElement field) {
const $JsonKey = const TypeChecker.fromRuntime(JsonKey);
var jsonKey = $JsonKey.annotationOf(field);
if (jsonKey != null) {
var jsonName = jsonKey.getField('jsonName').toStringValue();
return jsonName;
}
return fieldName;
} |
kevmoo
left a comment
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.
LGTM – let's see what @jakemac53 says...
|
See broken build – Ugh... |
lib/src/type_checker.dart
Outdated
| /// Returns the first constant annotating [element] that is this type. | ||
| /// | ||
| /// Otherwise returns `null`. | ||
| DartObject annotationOf(Element element) { |
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.
Should this be firstAnnotationOf? And then possibly add annotationsOf?
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.
Done.
| } | ||
|
|
||
| /// Returns `true` if representing the exact same class as [element]. | ||
| bool isExactly(Element element); |
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.
Should this be ClassElement?
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.
Good question. Originally I had it, but I changed because:
- Most APIs return
Element, notClassElement, and this avoids users having to cast all over. - There are other types not yet covered (like Function types) that are not classes but could be used here.
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.
ok, sgtm
lib/src/type_checker.dart
Outdated
| element is ClassElement && element.allSupertypes.any(isExactlyType); | ||
|
|
||
| /// Returns `true` if representing a super type of [staticType]. | ||
| bool isSuperType(DartType staticType) => isSuperOf(staticType.element); |
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.
nit: isSuperTypeOf for consistency
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.
Done.
|
|
||
| /// An abstraction around doing static type checking at compile/build time. | ||
| abstract class TypeChecker { | ||
| const TypeChecker._(); |
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.
Do you need this constructor? You should be able to delete it and remove the super constructor calls.
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.
I could remove it, but then the other classes couldn't be const. Since I wanted that anyway, I figured making the TypeChecker class itself not extendable is probably an OK thing to do.
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.
Ah ok just for the const, makes sense. We can always make this public later if somebody actually has a valid reason to extend it and files an issue.
lib/src/type_checker.dart
Outdated
| bool isSuperOf(Element element) => | ||
| isExactly(element) || | ||
| element is ClassElement && | ||
| element.allSupertypes.any((t) => t.element == _type.element); |
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.
Why is the logic different for checking super types? (here it checks for ClassElement equality where isExactly checks for DartType equality)
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.
Fixed, thanks!
lib/src/type_checker.dart
Outdated
| fragment: MirrorSystem.getName(mirror.simpleName), | ||
| ); | ||
| default: | ||
| throw new StateError('Cannot resolve "$sourceUri".'); |
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.
maybe add an additional note You must import the ${mirror.simpleName} class using a package: or dart: uri..
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.
Done.
lib/src/type_checker.dart
Outdated
| var sourceUri = element.source.uri; | ||
| switch (sourceUri.scheme) { | ||
| case 'dart': | ||
| if (sourceUri.pathSegments.isNotEmpty) { |
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.
Is it an error if this is empty? Also when is it more than one segment?
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.
Added a comment why.
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.
where? (maybe forgot to push a commit?)
|
|
||
| final core = resolver.getLibraryByName('dart.core'); | ||
| staticMap = core.getType('Map').type; | ||
| staticMapChecker = new TypeChecker.fromStatic(staticMap); |
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.
Might as well just create this inline in the test that uses them below like the others instead of creating them for all tests (same for staticHashMapChecker).
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.
The only reason I did this is to avoid creating a Resolver multiple times per test.
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.
oh right, setUpAll just runs once doesn't it, sgtm
test/type_checker_test.dart
Outdated
| }); | ||
|
|
||
| test('should not be a super type of dart:core#Map', () { | ||
| expect(checkMap().isSuperType(staticMap), isTrue); |
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.
Shouldn't this be isFalse?
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.
Done and fixed.
test/type_checker_test.dart
Outdated
| expect( | ||
| checkMap().isExactlyType(staticMap), | ||
| isTrue, | ||
| reason: '$checkMap != $staticMap', |
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.
nit: no trailing comma ;) (also below).
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.
Done.
jakemac53
left a comment
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.
Generally LGTM, but it would be good to also add tests for non-core classes if you don't mind.
| } | ||
|
|
||
| /// Returns `true` if representing the exact same class as [element]. | ||
| bool isExactly(Element element); |
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.
ok, sgtm
|
As discussed offline with @jakemac53, filed #161 to add additional test cases - need some infra build-out for pkg/build_test first. |
|
@matanlurey thoughts on the broken travis bits? |
|
@kevmoo Fixing now, I had some mismatch b/w New functionality normalizes the two (internally). Will upload as soon as all tests pass. |
|
@matanlurey for this PR or later – would be great to have a See 0046bdd#diff-c4274d5939b2f855cfba15318f2d42ebR250 Having to do |
|
@kevmoo Send a PR after I merge? I finally got this one green :P |
Deal. 👍 |
* Add TypeChecker class. * Added annotationOf. * Added a fallback case for dynamic. * Address comments. * Normalize. * Dartfmt.
* Add TypeChecker class. * Added annotationOf. * Added a fallback case for dynamic. * Address comments. * Normalize. * Dartfmt.
This will be nice to have versus stuffed into the AngularDart compiler, and it doesn't feel "right" going into a library like
build, which I think benefits from having a very small interface and low-threshold for changes.Advantages of this approach
dart:mirrors(for long-term safety).injectorangular.See
type_checker_test.dartfor some functional tests.Closes #136.