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

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

Issue 2665723002: Implement canonical name scheme in kernel. (Closed)
Patch Set: 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
kustermann 2017/02/01 13:00:54 Isn't this the canonical name of the enclosing lib
asgerf 2017/02/02 12:30:27 They are the same thing. I thought it would be cle
kustermann 2017/02/03 11:48:20 Up to you, but for all the other things, like Fiel
asgerf 2017/02/03 12:47:38 Done.
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.
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 Iterable<CanonicalName> get children =>
85 _children?.values ?? const <CanonicalName>[];
86
87 CanonicalName getChild(String name) {
88 var map = _children ??= <String, CanonicalName>{};
89 return map[name] ??= new CanonicalName._(this, name);
90 }
91
92 CanonicalName getChildFromUri(Uri uri) {
93 // Note that the Uri class caches its string representation, and all library
94 // URIs will be stringified for serialization anyway, so there is no
95 // significant cost for converting the Uri to a string here.
96 return getChild('$uri');
97 }
98
99 CanonicalName getChildFromQualifiedName(Name name) {
100 return name.isPrivate
101 ? getChild(name.libraryName.name).getChild(name.name)
102 : getChild(name.name);
103 }
104
105 CanonicalName getChildFromMember(Member member) {
106 return getChild(getMemberQualifier(member))
107 .getChildFromQualifiedName(member.name);
108 }
109
110 void linkTo(LinkedNode target) {
ahe 2017/01/30 17:16:16 Call this bind?
asgerf 2017/02/02 12:30:27 Changed to bindTo
111 if (definition == target) return;
112 if (definition != null) {
113 throw '$this is already bound';
114 }
115 if (target.canonicalName != null) {
116 throw 'Cannot bind $this to $target, target is already bound';
117 }
118 target.canonicalName = this;
119 this.definition = target;
120 }
121
122 void unlink() {
123 if (definition == null) return;
124 assert(definition.canonicalName == this);
125 definition.canonicalName = null;
126 definition = null;
kustermann 2017/02/01 13:00:54 Should this unlink() not also update the _children
asgerf 2017/02/02 12:30:27 'unlink' is not meant to "destroy" the name. It sh
127 }
128
129 String toString() => parent == null ? 'root' : '$parent::$name';
130
131 Library get asLibrary {
132 if (definition == null) throw '$this is not bound';
133 return definition as Library;
134 }
135
136 Class get asClass {
137 if (definition == null) throw '$this is not bound';
138 return definition as Class;
139 }
140
141 Member get asMember {
142 if (definition == null) throw '$this is not bound';
143 return definition as Member;
144 }
145
146 Constructor get asConstructor {
147 if (definition == null) throw '$this is not bound';
148 return definition as Constructor;
149 }
150
151 Procedure get asProcedure {
152 if (definition == null) throw '$this is not bound';
153 return definition as Procedure;
154 }
155
156 Field get asField {
157 if (definition == null) throw '$this is not bound';
158 return definition as Field;
159 }
160
161 static String getMemberQualifier(Member member) {
162 if (member is Procedure) {
163 if (member.isGetter) return '@getters';
164 if (member.isSetter) return '@setters';
165 return '@methods';
166 }
167 if (member is Field) {
168 return '@fields';
169 }
170 if (member is Constructor) {
171 return '@constructors';
172 }
173 throw 'Unexpected member: $member';
174 }
175 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698