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

Unified 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 side-by-side diff with in-line comments
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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/kernel/lib/canonical_name.dart
diff --git a/pkg/kernel/lib/canonical_name.dart b/pkg/kernel/lib/canonical_name.dart
new file mode 100644
index 0000000000000000000000000000000000000000..7bf05dc4507ccf12ad724daf9d10de4e9a5a5f29
--- /dev/null
+++ b/pkg/kernel/lib/canonical_name.dart
@@ -0,0 +1,149 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+library kernel.canonical_name;
+
+import 'ast.dart';
+
+/// A string sequence that identifies a library, class, or member.
+///
+/// Canonical names are organized in a prefix tree. Each node knows its
+/// parent, children, and the AST node it is currently bound to.
+///
+/// The following schema specifies how the canonical name of a given object
+/// is defined:
+///
+/// Library:
+/// URI of library
+///
+/// Class:
+/// Canonical name of enclosing library
+/// Name of class
+///
+/// Constructor:
+/// Canonical name of enclosing class or library
+/// "@constructors"
+/// Qualified name
+///
+/// Field:
+/// Canonical name of enclosing class or library
+/// "@fields"
+/// Qualified name
+///
+/// Procedure that is not an accessor:
+/// Canonical name of enclosing class or library
+/// "@methods"
+/// Qualified name
+///
+/// Procedure that is a getter:
+/// Canonical name of enclosing class or library
+/// "@getters"
+/// Qualified name
+///
+/// Procedure that is a setter:
+/// Canonical name of enclosing class or library
+/// "@setters"
+/// Qualified name
+///
+/// Qualified name:
+/// if private: URI of library
+/// Name text
+///
+/// The "qualified name" allows a member to have a name that is private to
+/// a library other than the one containing that member.
+class CanonicalName {
+ final CanonicalName parent;
+ final String name;
+
+ Map<String, CanonicalName> _children;
+
+ /// The library, class, or member bound to this name.
+ Reference reference;
+
+ /// Temporary index used during serialization.
+ int index = -1;
+
+ CanonicalName._(this.parent, this.name) {
+ assert(name != null);
+ }
+
+ CanonicalName.root()
+ : parent = null,
+ name = '';
+
+ bool get isRoot => parent == null;
+
+ Iterable<CanonicalName> get children =>
+ _children?.values ?? const <CanonicalName>[];
+
+ CanonicalName getChild(String name) {
+ var map = _children ??= <String, CanonicalName>{};
+ return map[name] ??= new CanonicalName._(this, name);
+ }
+
+ CanonicalName getChildFromUri(Uri uri) {
+ // Note that the Uri class caches its string representation, and all library
+ // URIs will be stringified for serialization anyway, so there is no
+ // significant cost for converting the Uri to a string here.
+ return getChild('$uri');
+ }
+
+ CanonicalName getChildFromQualifiedName(Name name) {
+ return name.isPrivate
+ ? getChildFromUri(name.library.importUri).getChild(name.name)
+ : getChild(name.name);
+ }
+
+ CanonicalName getChildFromMember(Member member) {
+ return getChild(getMemberQualifier(member))
+ .getChildFromQualifiedName(member.name);
+ }
+
+ void bindTo(Reference target) {
+ if (reference == target) return;
+ if (reference != null) {
+ throw '$this is already bound';
+ }
+ if (target.canonicalName != null) {
+ throw 'Cannot bind $this to ${target.node}, target is already bound to '
+ '${target.canonicalName}';
+ }
+ target.canonicalName = this;
+ this.reference = target;
+ }
+
+ void unbind() {
+ if (reference == null) return;
+ assert(reference.canonicalName == this);
+ reference.canonicalName = null;
+ reference = null;
+ }
+
+ void unbindAll() {
+ unbind();
+ for (var child in children) {
+ child.unbindAll();
+ }
+ }
+
+ String toString() => parent == null ? 'root' : '$parent::$name';
+
+ Reference getReference() {
+ return reference ??= (new Reference()..canonicalName = this);
+ }
+
+ static String getMemberQualifier(Member member) {
+ if (member is Procedure) {
+ if (member.isGetter) return '@getters';
+ if (member.isSetter) return '@setters';
+ return '@methods';
+ }
+ if (member is Field) {
+ return '@fields';
+ }
+ if (member is Constructor) {
+ return '@constructors';
+ }
+ throw 'Unexpected member: $member';
+ }
+}
« 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