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

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

Issue 2665723002: Implement canonical name scheme in kernel. (Closed)
Patch Set: Address Kevin's 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
« no previous file with comments | « pkg/kernel/lib/binary/tag.dart ('k') | pkg/kernel/lib/clone.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 /// Canonical name 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 Reference reference;
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 bool get isRoot => parent == null;
75
76 Iterable<CanonicalName> get children =>
77 _children?.values ?? const <CanonicalName>[];
78
79 CanonicalName getChild(String name) {
80 var map = _children ??= <String, CanonicalName>{};
81 return map[name] ??= new CanonicalName._(this, name);
82 }
83
84 CanonicalName getChildFromUri(Uri uri) {
85 // Note that the Uri class caches its string representation, and all library
86 // URIs will be stringified for serialization anyway, so there is no
87 // significant cost for converting the Uri to a string here.
88 return getChild('$uri');
89 }
90
91 CanonicalName getChildFromQualifiedName(Name name) {
92 return name.isPrivate
93 ? getChildFromUri(name.library.importUri).getChild(name.name)
94 : getChild(name.name);
95 }
96
97 CanonicalName getChildFromMember(Member member) {
98 return getChild(getMemberQualifier(member))
99 .getChildFromQualifiedName(member.name);
100 }
101
102 void bindTo(Reference target) {
103 if (reference == target) return;
104 if (reference != null) {
105 throw '$this is already bound';
106 }
107 if (target.canonicalName != null) {
108 throw 'Cannot bind $this to ${target.node}, target is already bound to '
109 '${target.canonicalName}';
110 }
111 target.canonicalName = this;
112 this.reference = target;
113 }
114
115 void unbind() {
116 if (reference == null) return;
117 assert(reference.canonicalName == this);
118 reference.canonicalName = null;
119 reference = null;
120 }
121
122 void unbindAll() {
123 unbind();
124 for (var child in children) {
125 child.unbindAll();
126 }
127 }
128
129 String toString() => parent == null ? 'root' : '$parent::$name';
130
131 Reference getReference() {
132 return reference ??= (new Reference()..canonicalName = this);
133 }
134
135 static String getMemberQualifier(Member member) {
136 if (member is Procedure) {
137 if (member.isGetter) return '@getters';
138 if (member.isSetter) return '@setters';
139 return '@methods';
140 }
141 if (member is Field) {
142 return '@fields';
143 }
144 if (member is Constructor) {
145 return '@constructors';
146 }
147 throw 'Unexpected member: $member';
148 }
149 }
OLDNEW
« no previous file with comments | « pkg/kernel/lib/binary/tag.dart ('k') | pkg/kernel/lib/clone.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698