Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(235)

Side by Side Diff: pkg/kernel/lib/canonical_name.dart

Issue 2665723002: Implement canonical name scheme in kernel. (Closed)
Patch Set: Address comments Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4 library kernel.canonical_name;
5
6 import 'ast.dart';
7
8 /// A string sequence that identifies a library, class, or member.
9 ///
10 /// Canonical names are organized in a prefix tree. Each node knows its
11 /// parent, children, and the AST node it is currently bound to.
12 ///
13 /// The following schema specifies how the canonical name of a given object
14 /// is defined:
15 ///
16 /// Library:
17 /// URI of library
18 ///
19 /// Class:
20 /// URI of enclosing library
21 /// Name of class
22 ///
23 /// Constructor:
24 /// Canonical name of enclosing class or library
25 /// "@constructors"
26 /// Qualified name
27 ///
28 /// Field:
29 /// Canonical name of enclosing class or library
30 /// "@fields"
31 /// Qualified name
32 ///
33 /// Procedure that is not an accessor:
34 /// Canonical name of enclosing class or library
35 /// "@methods"
36 /// Qualified name
37 ///
38 /// Procedure that is a getter:
39 /// Canonical name of enclosing class or library
40 /// "@getters"
41 /// Qualified name
42 ///
43 /// Procedure that is a setter:
44 /// Canonical name of enclosing class or library
45 /// "@setters"
46 /// Qualified name
47 ///
48 /// Qualified name:
49 /// if private: URI of library
50 /// Name text
51 ///
52 /// The "qualified name" allows a member to have a name that is private to
53 /// a library other than the one containing that member.
54 class CanonicalName {
55 final CanonicalName parent;
56 final String name;
57
58 Map<String, CanonicalName> _children;
59
60 /// The library, class, or member bound to this name.
61 LinkedNode definition;
62
63 /// Temporary index used during serialization.
64 int index = -1;
65
66 CanonicalName._(this.parent, this.name) {
67 assert(name != null);
68 }
69
70 CanonicalName.root()
71 : parent = null,
72 name = '';
73
74 /// Used as temporary measure to get the dart2js-kernel adaptor working.
ahe 2017/02/02 16:24:01 Add TODO to remove?
asgerf 2017/02/03 10:31:16 Same as previous answer.
75 ///
76 /// This canonical name cannot be used in serialization but can hold in-memory
77 /// references.
78 CanonicalName.dummy()
79 : parent = null,
80 name = 'dummy';
81
82 bool get isRoot => parent == null;
83
84 /// True if this is a fake canonical name object used by the dart2js/kernel
ahe 2017/02/02 16:24:01 Ditto?
asgerf 2017/02/03 10:31:16 Same as previous answer.
85 /// adaptor.
86 bool get isDummy => parent == null && name == 'dummy';
87
88 Iterable<CanonicalName> get children =>
89 _children?.values ?? const <CanonicalName>[];
90
91 CanonicalName getChild(String name) {
92 var map = _children ??= <String, CanonicalName>{};
93 return map[name] ??= new CanonicalName._(this, name);
94 }
95
96 CanonicalName getChildFromUri(Uri uri) {
97 // Note that the Uri class caches its string representation, and all library
98 // URIs will be stringified for serialization anyway, so there is no
99 // significant cost for converting the Uri to a string here.
100 return getChild('$uri');
101 }
102
103 CanonicalName getChildFromQualifiedName(Name name) {
104 return name.isPrivate
105 ? getChild(name.libraryName.name).getChild(name.name)
106 : getChild(name.name);
107 }
108
109 CanonicalName getChildFromMember(Member member) {
110 return getChild(getMemberQualifier(member))
111 .getChildFromQualifiedName(member.name);
112 }
113
114 void bindTo(LinkedNode target) {
115 if (definition == target) return;
116 if (definition != null) {
117 throw '$this is already bound';
118 }
119 if (target.canonicalName != null) {
120 throw 'Cannot bind $this to $target, target is already bound';
121 }
122 target.canonicalName = this;
123 this.definition = target;
124 }
125
126 void unbind() {
127 if (definition == null) return;
128 assert(definition.canonicalName == this);
129 definition.canonicalName = null;
130 definition = null;
131 }
132
133 String toString() => parent == null ? 'root' : '$parent::$name';
134
135 Library get asLibrary {
ahe 2017/02/02 16:24:01 Nice!
asgerf 2017/02/03 10:31:16 Acknowledged.
136 if (definition == null) throw '$this is not bound';
137 return definition as Library;
138 }
139
140 Class get asClass {
141 if (definition == null) throw '$this is not bound';
142 return definition as Class;
143 }
144
145 Member get asMember {
146 if (definition == null) throw '$this is not bound';
147 return definition as Member;
148 }
149
150 Constructor get asConstructor {
151 if (definition == null) throw '$this is not bound';
152 return definition as Constructor;
153 }
154
155 Procedure get asProcedure {
156 if (definition == null) throw '$this is not bound';
157 return definition as Procedure;
158 }
159
160 Field get asField {
161 if (definition == null) throw '$this is not bound';
162 return definition as Field;
163 }
164
165 static String getMemberQualifier(Member member) {
166 if (member is Procedure) {
167 if (member.isGetter) return '@getters';
168 if (member.isSetter) return '@setters';
169 return '@methods';
170 }
171 if (member is Field) {
172 return '@fields';
173 }
174 if (member is Constructor) {
175 return '@constructors';
176 }
177 throw 'Unexpected member: $member';
178 }
179 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698