Skip to content

Commit 57a1778

Browse files
committed
don't leak syntax classes
1 parent 2941e66 commit 57a1778

File tree

7 files changed

+166
-76
lines changed

7 files changed

+166
-76
lines changed

pkgs/record_use/lib/src/constant.dart

Lines changed: 47 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ sealed class Constant {
2121
/// [constants] needs to be passed, as the [Constant]s are normalized and
2222
/// stored separately in the JSON.
2323
Map<String, Object?> toJson(Map<Constant, int> constants) =>
24-
toSyntax(constants).json;
24+
_toSyntax(constants).json;
2525

2626
/// Converts this [Constant] object to a syntax representation.
27-
ConstantSyntax toSyntax(Map<Constant, int> constants);
27+
ConstantSyntax _toSyntax(Map<Constant, int> constants);
2828

2929
/// Converts this [Constant] to the value it represents.
3030
Object? toValue() => switch (this) {
@@ -46,30 +46,30 @@ sealed class Constant {
4646
static Constant fromJson(
4747
Map<String, Object?> value,
4848
List<Constant> constants,
49-
) => fromSyntax(ConstantSyntax.fromJson(value), constants);
49+
) => _fromSyntax(ConstantSyntax.fromJson(value), constants);
5050

5151
/// Creates a [Constant] object from its syntax representation.
52-
static Constant fromSyntax(ConstantSyntax syntax, List<Constant> constants) =>
53-
switch (syntax) {
54-
NullConstantSyntax() => const NullConstant(),
55-
BoolConstantSyntax(:final value) => BoolConstant(value),
56-
IntConstantSyntax(:final value) => IntConstant(value),
57-
StringConstantSyntax(:final value) => StringConstant(value),
58-
ListConstantSyntax(:final value) => ListConstant(
59-
value!.cast<int>().map((i) => constants[i]).toList(),
60-
),
61-
MapConstantSyntax(:final value) => MapConstant(
62-
value.json.map(
63-
(key, value) => MapEntry(key, constants[value as int]),
64-
),
65-
),
66-
InstanceConstantSyntax(value: final value) => InstanceConstant(
67-
fields: (value?.json ?? {}).map(
68-
(key, value) => MapEntry(key, constants[value as int]),
69-
),
70-
),
71-
_ => throw UnimplementedError('This type is not a supported constant'),
72-
};
52+
static Constant _fromSyntax(
53+
ConstantSyntax syntax,
54+
List<Constant> constants,
55+
) => switch (syntax) {
56+
NullConstantSyntax() => const NullConstant(),
57+
BoolConstantSyntax(:final value) => BoolConstant(value),
58+
IntConstantSyntax(:final value) => IntConstant(value),
59+
StringConstantSyntax(:final value) => StringConstant(value),
60+
ListConstantSyntax(:final value) => ListConstant(
61+
value!.cast<int>().map((i) => constants[i]).toList(),
62+
),
63+
MapConstantSyntax(:final value) => MapConstant(
64+
value.json.map((key, value) => MapEntry(key, constants[value as int])),
65+
),
66+
InstanceConstantSyntax(value: final value) => InstanceConstant(
67+
fields: (value?.json ?? {}).map(
68+
(key, value) => MapEntry(key, constants[value as int]),
69+
),
70+
),
71+
_ => throw UnimplementedError('This type is not a supported constant'),
72+
};
7373
}
7474

7575
/// Represents the `null` constant value.
@@ -78,7 +78,7 @@ final class NullConstant extends Constant {
7878
const NullConstant() : super();
7979

8080
@override
81-
NullConstantSyntax toSyntax(Map<Constant, int> constants) =>
81+
NullConstantSyntax _toSyntax(Map<Constant, int> constants) =>
8282
NullConstantSyntax();
8383

8484
@override
@@ -114,7 +114,7 @@ final class BoolConstant extends PrimitiveConstant<bool> {
114114
const BoolConstant(super.value);
115115

116116
@override
117-
BoolConstantSyntax toSyntax(Map<Constant, int> constants) =>
117+
BoolConstantSyntax _toSyntax(Map<Constant, int> constants) =>
118118
BoolConstantSyntax(value: value);
119119
}
120120

@@ -124,7 +124,7 @@ final class IntConstant extends PrimitiveConstant<int> {
124124
const IntConstant(super.value);
125125

126126
@override
127-
IntConstantSyntax toSyntax(Map<Constant, int> constants) =>
127+
IntConstantSyntax _toSyntax(Map<Constant, int> constants) =>
128128
IntConstantSyntax(value: value);
129129
}
130130

@@ -134,7 +134,7 @@ final class StringConstant extends PrimitiveConstant<String> {
134134
const StringConstant(super.value);
135135

136136
@override
137-
StringConstantSyntax toSyntax(Map<Constant, int> constants) =>
137+
StringConstantSyntax _toSyntax(Map<Constant, int> constants) =>
138138
StringConstantSyntax(value: value);
139139
}
140140

@@ -157,7 +157,7 @@ final class ListConstant<T extends Constant> extends Constant {
157157
}
158158

159159
@override
160-
ListConstantSyntax toSyntax(Map<Constant, int> constants) =>
160+
ListConstantSyntax _toSyntax(Map<Constant, int> constants) =>
161161
ListConstantSyntax(
162162
value: value.map((constant) => constants[constant]).toList(),
163163
);
@@ -182,11 +182,12 @@ final class MapConstant<T extends Constant> extends Constant {
182182
}
183183

184184
@override
185-
MapConstantSyntax toSyntax(Map<Constant, int> constants) => MapConstantSyntax(
186-
value: JsonObjectSyntax.fromJson(
187-
value.map((key, constant) => MapEntry(key, constants[constant]!)),
188-
),
189-
);
185+
MapConstantSyntax _toSyntax(Map<Constant, int> constants) =>
186+
MapConstantSyntax(
187+
value: JsonObjectSyntax.fromJson(
188+
value.map((key, constant) => MapEntry(key, constants[constant]!)),
189+
),
190+
);
190191
}
191192

192193
/// A constant instance of a class with its fields
@@ -201,7 +202,7 @@ final class InstanceConstant extends Constant {
201202
const InstanceConstant({required this.fields});
202203

203204
@override
204-
InstanceConstantSyntax toSyntax(Map<Constant, int> constants) =>
205+
InstanceConstantSyntax _toSyntax(Map<Constant, int> constants) =>
205206
InstanceConstantSyntax(
206207
value: fields.isNotEmpty
207208
? JsonObjectSyntax.fromJson(
@@ -222,3 +223,14 @@ final class InstanceConstant extends Constant {
222223
@override
223224
int get hashCode => deepHash(fields);
224225
}
226+
227+
/// Package private (protected) methods for [Constant].
228+
///
229+
/// This avoids bloating the public API and public API docs and prevents
230+
/// internal types from leaking from the API.
231+
extension ConstantProtected on Constant {
232+
ConstantSyntax toSyntax(Map<Constant, int> constants) => _toSyntax(constants);
233+
234+
static Constant fromSyntax(ConstantSyntax syntax, List<Constant> constants) =>
235+
Constant._fromSyntax(syntax, constants);
236+
}

pkgs/record_use/lib/src/definition.dart

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5-
import 'identifier.dart' show Identifier;
5+
import 'identifier.dart';
66
import 'syntax.g.dart';
77

88
/// A definition is an [identifier] with its [loadingUnit].
@@ -13,16 +13,16 @@ class Definition {
1313
const Definition({required this.identifier, this.loadingUnit});
1414

1515
factory Definition.fromJson(Map<String, Object?> json) =>
16-
Definition.fromSyntax(DefinitionSyntax.fromJson(json));
16+
Definition._fromSyntax(DefinitionSyntax.fromJson(json));
1717

18-
factory Definition.fromSyntax(DefinitionSyntax syntax) => Definition(
19-
identifier: Identifier.fromSyntax(syntax.identifier),
18+
factory Definition._fromSyntax(DefinitionSyntax syntax) => Definition(
19+
identifier: IdentifierProtected.fromSyntax(syntax.identifier),
2020
loadingUnit: syntax.loadingUnit,
2121
);
2222

23-
Map<String, Object?> toJson() => toSyntax().json;
23+
Map<String, Object?> toJson() => _toSyntax().json;
2424

25-
DefinitionSyntax toSyntax() => DefinitionSyntax(
25+
DefinitionSyntax _toSyntax() => DefinitionSyntax(
2626
identifier: identifier.toSyntax(),
2727
loadingUnit: loadingUnit,
2828
);
@@ -39,3 +39,14 @@ class Definition {
3939
@override
4040
int get hashCode => Object.hash(identifier, loadingUnit);
4141
}
42+
43+
/// Package private (protected) methods for [Definition].
44+
///
45+
/// This avoids bloating the public API and public API docs and prevents
46+
/// internal types from leaking from the API.
47+
extension DefinitionProtected on Definition {
48+
DefinitionSyntax toSyntax() => _toSyntax();
49+
50+
static Definition fromSyntax(DefinitionSyntax syntax) =>
51+
Definition._fromSyntax(syntax);
52+
}

pkgs/record_use/lib/src/identifier.dart

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,17 @@ class Identifier {
3939

4040
/// Creates an [Identifier] object from its JSON representation.
4141
factory Identifier.fromJson(Map<String, Object?> json) =>
42-
Identifier.fromSyntax(IdentifierSyntax.fromJson(json));
42+
Identifier._fromSyntax(IdentifierSyntax.fromJson(json));
4343

4444
/// Creates an [Identifier] object from its syntax representation.
45-
factory Identifier.fromSyntax(IdentifierSyntax syntax) =>
45+
factory Identifier._fromSyntax(IdentifierSyntax syntax) =>
4646
Identifier(importUri: syntax.uri, scope: syntax.scope, name: syntax.name);
4747

4848
/// Converts this [Identifier] object to a JSON representation.
49-
Map<String, Object?> toJson() => toSyntax().json;
49+
Map<String, Object?> toJson() => _toSyntax().json;
5050

5151
/// Converts this [Identifier] object to a syntax representation.
52-
IdentifierSyntax toSyntax() =>
52+
IdentifierSyntax _toSyntax() =>
5353
IdentifierSyntax(uri: importUri, scope: scope, name: name);
5454

5555
@override
@@ -65,3 +65,14 @@ class Identifier {
6565
@override
6666
int get hashCode => Object.hash(importUri, scope, name);
6767
}
68+
69+
/// Package private (protected) methods for [Identifier].
70+
///
71+
/// This avoids bloating the public API and public API docs and prevents
72+
/// internal types from leaking from the API.
73+
extension IdentifierProtected on Identifier {
74+
IdentifierSyntax toSyntax() => _toSyntax();
75+
76+
static Identifier fromSyntax(IdentifierSyntax syntax) =>
77+
Identifier._fromSyntax(syntax);
78+
}

pkgs/record_use/lib/src/location.dart

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ class Location {
1212
const Location({required this.uri, this.line, this.column});
1313

1414
factory Location.fromJson(Map<String, Object?> map) =>
15-
Location.fromSyntax(LocationSyntax.fromJson(map));
15+
Location._fromSyntax(LocationSyntax.fromJson(map));
1616

17-
factory Location.fromSyntax(LocationSyntax syntax) =>
17+
factory Location._fromSyntax(LocationSyntax syntax) =>
1818
Location(uri: syntax.uri);
1919

20-
Map<String, Object?> toJson() => toSyntax().json;
20+
Map<String, Object?> toJson() => _toSyntax().json;
2121

22-
LocationSyntax toSyntax() => LocationSyntax(uri: uri);
22+
LocationSyntax _toSyntax() => LocationSyntax(uri: uri);
2323

2424
@override
2525
bool operator ==(Object other) {
@@ -34,3 +34,14 @@ class Location {
3434
@override
3535
int get hashCode => Object.hash(uri, line, column);
3636
}
37+
38+
/// Package private (protected) methods for [Location].
39+
///
40+
/// This avoids bloating the public API and public API docs and prevents
41+
/// internal types from leaking from the API.
42+
extension LocationProtected on Location {
43+
LocationSyntax toSyntax() => _toSyntax();
44+
45+
static Location fromSyntax(LocationSyntax syntax) =>
46+
Location._fromSyntax(syntax);
47+
}

pkgs/record_use/lib/src/metadata.dart

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ class Metadata {
1818
const Metadata._(this._syntax);
1919

2020
factory Metadata.fromJson(Map<String, Object?> json) =>
21-
Metadata.fromSyntax(MetadataSyntax.fromJson(json));
22-
23-
factory Metadata.fromSyntax(MetadataSyntax syntax) => Metadata._(syntax);
21+
Metadata._(MetadataSyntax.fromJson(json));
2422

2523
/// The underlying data.
2624
///
@@ -31,8 +29,6 @@ class Metadata {
3129

3230
Map<String, Object?> toJson() => _syntax.json;
3331

34-
MetadataSyntax toSyntax() => _syntax;
35-
3632
Version get version => Version.parse(_syntax.version);
3733
String get comment => _syntax.comment;
3834

@@ -46,3 +42,13 @@ class Metadata {
4642
@override
4743
int get hashCode => deepHash(json);
4844
}
45+
46+
/// Package private (protected) methods for [Metadata].
47+
///
48+
/// This avoids bloating the public API and public API docs and prevents
49+
/// internal types from leaking from the API.
50+
extension MetadataProtected on Metadata {
51+
MetadataSyntax toSyntax() => _syntax;
52+
53+
static Metadata fromSyntax(MetadataSyntax syntax) => Metadata._(syntax);
54+
}

pkgs/record_use/lib/src/recordings.dart

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import 'constant.dart';
99
import 'definition.dart';
1010
import 'helper.dart';
1111
import 'identifier.dart';
12-
import 'location.dart' show Location;
12+
import 'location.dart';
1313
import 'metadata.dart';
1414
import 'reference.dart';
1515
import 'syntax.g.dart';
@@ -56,7 +56,7 @@ class Recordings {
5656
factory Recordings.fromJson(Map<String, Object?> json) {
5757
try {
5858
final syntax = RecordedUsesSyntax.fromJson(json);
59-
return Recordings.fromSyntax(syntax);
59+
return Recordings._fromSyntax(syntax);
6060
} on Exception catch (e) {
6161
throw ArgumentError('''
6262
Invalid JSON format for Recordings:
@@ -66,18 +66,18 @@ Error: $e
6666
}
6767
}
6868

69-
factory Recordings.fromSyntax(RecordedUsesSyntax syntax) {
69+
factory Recordings._fromSyntax(RecordedUsesSyntax syntax) {
7070
final constants = <Constant>[];
7171
for (final constantSyntax in syntax.constants ?? <ConstantSyntax>[]) {
72-
final constant = Constant.fromSyntax(constantSyntax, constants);
72+
final constant = ConstantProtected.fromSyntax(constantSyntax, constants);
7373
if (!constants.contains(constant)) {
7474
constants.add(constant);
7575
}
7676
}
7777

7878
final locations = <Location>[];
7979
for (final locationSyntax in syntax.locations ?? <LocationSyntax>[]) {
80-
final location = Location.fromSyntax(locationSyntax);
80+
final location = LocationProtected.fromSyntax(locationSyntax);
8181
if (!locations.contains(location)) {
8282
locations.add(location);
8383
}
@@ -87,20 +87,25 @@ Error: $e
8787
final instancesForDefinition = <Definition, List<InstanceReference>>{};
8888

8989
for (final recordingSyntax in syntax.recordings ?? <RecordingSyntax>[]) {
90-
final definition = Definition.fromSyntax(recordingSyntax.definition);
90+
final definition = DefinitionProtected.fromSyntax(
91+
recordingSyntax.definition,
92+
);
9193
if (recordingSyntax.calls case final callSyntaxes?) {
9294
final callReferences = callSyntaxes
9395
.map<CallReference>(
94-
(callSyntax) =>
95-
CallReference.fromSyntax(callSyntax, constants, locations),
96+
(callSyntax) => CallReferenceProtected.fromSyntax(
97+
callSyntax,
98+
constants,
99+
locations,
100+
),
96101
)
97102
.toList();
98103
callsForDefinition[definition] = callReferences;
99104
}
100105
if (recordingSyntax.instances case final instanceSyntaxes?) {
101106
final instanceReferences = instanceSyntaxes
102107
.map<InstanceReference>(
103-
(instanceSyntax) => InstanceReference.fromSyntax(
108+
(instanceSyntax) => InstanceReferenceProtected.fromSyntax(
104109
instanceSyntax,
105110
constants,
106111
locations,
@@ -112,7 +117,7 @@ Error: $e
112117
}
113118

114119
return Recordings(
115-
metadata: Metadata.fromSyntax(syntax.metadata),
120+
metadata: MetadataProtected.fromSyntax(syntax.metadata),
116121
callsForDefinition: callsForDefinition,
117122
instancesForDefinition: instancesForDefinition,
118123
);
@@ -121,9 +126,9 @@ Error: $e
121126
/// Encodes this object into a JSON representation.
122127
///
123128
/// This method normalizes identifiers and constants for storage efficiency.
124-
Map<String, Object?> toJson() => toSyntax().json;
129+
Map<String, Object?> toJson() => _toSyntax().json;
125130

126-
RecordedUsesSyntax toSyntax() {
131+
RecordedUsesSyntax _toSyntax() {
127132
final constantsIndex = {
128133
...callsForDefinition.values
129134
.expand((calls) => calls)

0 commit comments

Comments
 (0)