Skip to content

Commit

Permalink
Experimenting on top of type_hierarchy: use the wire type.
Browse files Browse the repository at this point in the history
  • Loading branch information
davidmorgan committed Oct 29, 2024
1 parent 614a7a6 commit 3a923d2
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 2 deletions.
80 changes: 79 additions & 1 deletion pkgs/dart_model/lib/src/dart_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,63 @@
// BSD-style license that can be found in the LICENSE file.

import 'dart_model.g.dart';
import 'json_buffer/json_buffer_builder.dart';
import 'json_buffer/json_buffer_builder.dart' hide Type;
import 'lazy_merged_map.dart';
import 'scopes.dart';

export 'dart_model.g.dart';

extension Decl on Declaration {
/*WireType get wireType {
final path = MacroScope.current.model.pathOf(node)!;
final secondLast = path[path.length - 2];
switch (secondLast) {
case 'members':
return WireType.member;
case 'scopes':
return WireType.interface;
default:
throw UnsupportedError('Unsupported path: $path');
}
}*/

WireType get wireType => Cast.fromJson(node).wireType;

Cast get cast => Cast.fromJson(node);
}

enum WireType {
member,
interface;
}

extension type Cast.fromJson(Map<String, Object?> node) {
WireType get wireType {
final path = MacroScope.current.model.pathOf(node)!;
final secondLast = path[path.length - 2];
switch (secondLast) {
case 'members':
return WireType.member;
case 'scopes':
return WireType.interface;
default:
throw UnsupportedError('Unsupported path: $path');
}
}

bool get isMember => wireType == WireType.member;
Member? get maybeMember => isMember ? asMember : null;
Member get asMember => wireType == WireType.member
? Member.fromJson(node)
: throw UnsupportedError('Not a member: $this');

bool get isInterface => wireType == WireType.interface;
Interface? get maybeInterface => isInterface ? asInterface : null;
Interface get asInterface => wireType == WireType.interface
? Interface.fromJson(node)
: throw UnsupportedError('Not a member: $this');
}

extension QualifiedNameExtension on QualifiedName {
String get asString =>
'$uri#${scope == null ? '' : '$scope${isStatic! ? '::' : '.'}'}$name';
Expand Down Expand Up @@ -98,6 +149,33 @@ extension ModelExtension on Model {
'are supported for now. $path');
}

List<String>? pathOf(Map<String, Object?> model) {
var parent = _getParent(model);
if (parent == null) return null;
final path = <String>[];
path.add(_keyOf(model, parent));
var previousParent = parent;

// Checks if any merged map of `left` == any merged map of `right.
bool isEqualNested(Map<String, Object?> left, Map<String, Object?> right) {
if (left == right) return true;
return left.expand.any((l) => right.expand.contains(l));
}

while (true) {
parent = _getParent(previousParent);
if (parent == null) return null;

/// We reached this models node, stop searching higher.
if (isEqualNested(parent, node)) break;

path.insert(0, _keyOf(previousParent, parent));
previousParent = parent;
}

return path;
}

/// Returns the key of [value] in [map].
///
/// Throws if [value] is not in [map].
Expand Down
36 changes: 35 additions & 1 deletion pkgs/dart_model/test/model_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ void main() {
])
..members['_root'] = Member(
properties: Properties(isField: true, isStatic: false),
namedParameters: [],
)));
});
});
Expand All @@ -44,7 +45,8 @@ void main() {
],
'members': {
'_root': {
'properties': {'isField': true, 'isStatic': false}
'properties': {'isField': true, 'isStatic': false},
'namedParameters': <Map<String, Object?>>[],
}
},
'properties': {'isClass': true}
Expand Down Expand Up @@ -214,6 +216,38 @@ void main() {
expect(copiedModel.qualifiedNameOf(member.node), null);
expect(model.qualifiedNameOf(copiedMember.node), null);
});

test('Declaration', () {
Scope.macro.run(() {
MacroScope.current.addModel(model);
final interface = model
.uris['package:dart_model/dart_model.dart']!.scopes['JsonData']!;
final member = interface.members['_root']!;

expect(member.wireType, WireType.member);
expect(interface.wireType, WireType.interface);

expect(member.cast.wireType, WireType.member);
expect(interface.cast.wireType, WireType.interface);

String produceOutput(Declaration declaration) {
final maybeMember = declaration.cast.maybeMember;
final maybeInterface = declaration.cast.maybeInterface;
return [
'declaration:${declaration.properties.toString()}',
if (maybeMember != null)
'member:${maybeMember.namedParameters.toString()}',
if (maybeInterface != null)
'interface:${maybeInterface.members.length}',
].toString();
}

expect(produceOutput(member),
'[declaration:{isField: true, isStatic: false}, member:[]]');
expect(produceOutput(interface),
'[declaration:{isClass: true}, interface:1]');
});
});
});

group('QualifiedName', () {
Expand Down

0 comments on commit 3a923d2

Please sign in to comment.