Chromium Code Reviews| 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()); |