Chromium Code Reviews| OLD | NEW |
|---|---|
| (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 } | |
| OLD | NEW |