Index: runtime/vm/object.cc |
=================================================================== |
--- runtime/vm/object.cc (revision 24709) |
+++ runtime/vm/object.cc (working copy) |
@@ -188,10 +188,11 @@ |
// get:foo -> foo |
// set:foo -> foo= |
// |
-// Private name mangling is removed, possibly twice: |
+// Private name mangling is removed, possibly multiple times: |
// |
// _ReceivePortImpl@6be832b -> _ReceivePortImpl |
-// _ReceivePortImpl@6be832b._internal@6be832b -> +ReceivePortImpl._internal |
+// _ReceivePortImpl@6be832b._internal@6be832b -> _ReceivePortImpl._internal |
+// _C@0x2b4ab9cc&_E@0x2b4ab9cc&_F@0x2b4ab9cc -> _C&_E&_F |
// |
// The trailing . on the default constructor name is dropped: |
// |
@@ -204,58 +205,70 @@ |
// _MyClass@6b3832b.named -> _MyClass.named |
// |
static RawString* IdentifierPrettyName(const String& name) { |
- intptr_t len = name.Length(); |
- intptr_t start = 0; |
- intptr_t at_pos = len; // Position of '@' in the name. |
- intptr_t dot_pos = len; // Position of '.' in the name. |
- bool is_setter = false; |
- |
if (name.Equals(Symbols::TopLevel())) { |
// Name of invisible top-level class. |
return Symbols::Empty().raw(); |
} |
- for (int i = start; i < name.Length(); i++) { |
- if (name.CharAt(i) == ':') { |
- ASSERT(start == 0); |
- if (name.CharAt(0) == 's') { |
- is_setter = true; |
+ |
+ // First remove all private name mangling. |
+ String& unmangled_name = String::Handle(Symbols::Empty().raw()); |
+ String& segment = String::Handle(); |
+ intptr_t start_pos = 0; |
+ for (intptr_t i = 0; i < name.Length(); i++) { |
+ if (name.CharAt(i) == '@') { |
+ // Append the current segment to the unmangled name. |
+ segment = String::SubString(name, start_pos, (i - start_pos)); |
+ unmangled_name = String::Concat(unmangled_name, segment); |
+ |
+ // Advance until past the name mangling. |
+ i++; // Skip the '@'. |
+ while ((i < name.Length()) && |
+ (name.CharAt(i) != '&') && |
+ (name.CharAt(i) != '.')) { |
+ i++; |
} |
- start = i + 1; |
- } else if (name.CharAt(i) == '@') { |
- ASSERT(at_pos == len); |
- at_pos = i; |
- } else if (name.CharAt(i) == '.') { |
- dot_pos = i; |
- break; |
+ start_pos = i; |
+ i--; // Account for for-loop increment. |
hausner
2013/07/03 16:24:58
DBC: Drop the 'for', just use 'while'. It's cleane
|
} |
} |
- intptr_t limit = (at_pos < dot_pos ? at_pos : dot_pos); |
- if (start == 0 && limit == len) { |
- // This name is fine as it is. |
- return name.raw(); |
+ if (start_pos == 0) { |
+ // No name unmangling needed, reuse the name that was passed in. |
+ unmangled_name = name.raw(); |
+ } else if (name.Length() != start_pos) { |
+ // Append the last segment. |
+ segment = String::SubString(name, start_pos, (name.Length() - start_pos)); |
+ unmangled_name = String::Concat(unmangled_name, segment); |
} |
- const String& result = |
- String::Handle(String::SubString(name, start, (limit - start))); |
+ intptr_t len = unmangled_name.Length(); |
+ intptr_t start = 0; |
+ intptr_t dot_pos = -1; // Position of '.' in the name, if any. |
+ bool is_setter = false; |
- // Look for a second '@' now to correctly handle names like |
- // "_ReceivePortImpl@6be832b._internal@6be832b". |
- at_pos = len; |
- for (int i = dot_pos; i < name.Length(); i++) { |
- if (name.CharAt(i) == '@') { |
- ASSERT(at_pos == len); |
- at_pos = i; |
+ for (intptr_t i = start; i < len; i++) { |
+ if (unmangled_name.CharAt(i) == ':') { |
+ ASSERT(start == 0); // Only one : is possible in getters or setters. |
+ if (unmangled_name.CharAt(0) == 's') { |
+ is_setter = true; |
+ } |
+ start = i + 1; |
+ } else if (unmangled_name.CharAt(i) == '.') { |
+ ASSERT(dot_pos == -1); // Only one dot is supported. |
hausner
2013/07/03 16:24:58
What about the case of a qualified (imported) memb
|
+ dot_pos = i; |
} |
} |
- intptr_t suffix_len = at_pos - dot_pos; |
- if (suffix_len > 1) { |
- // This is a named constructor. Add the name back to the string. |
- const String& suffix = |
- String::Handle(String::SubString(name, dot_pos, suffix_len)); |
- return String::Concat(result, suffix); |
+ if ((start == 0) && (dot_pos == -1)) { |
+ // This unmangled_name is fine as it is. |
+ return unmangled_name.raw(); |
} |
+ // Drop the trailing dot if needed. |
+ intptr_t end = ((dot_pos + 1) == len) ? dot_pos : len; |
+ |
+ const String& result = |
+ String::Handle(String::SubString(unmangled_name, start, (end - start))); |
+ |
if (is_setter) { |
// Setters need to end with '='. |
return String::Concat(result, Symbols::Equals()); |