observatory: add class view based on end token position

vm: add method to compute end token positions

BUG=
R=johnmccutchan@google.com

Review URL: https://codereview.chromium.org//361743002

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@37964 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
mlippautz@google.com 2014-07-02 23:22:50 +00:00
parent d0d175bf69
commit f7e931bb7d
13 changed files with 42074 additions and 77698 deletions

View file

@ -2496,6 +2496,7 @@ hr {
<polymer-element name="eval-box" extends="observatory-element">
<template>
<style>
@ -3404,6 +3405,42 @@ hr {
<polymer-element name="script-inset" extends="observatory-element">
<template>
<style>
.sourceInset {
padding-left: 15%;
padding-right: 15%;
}
.grayBox {
width: 100%;
background-color: #f5f5f5;
border: 1px solid #ccc;
padding: 10px;
}
</style>
<div class="sourceInset">
<content></content>
<div class="grayBox">
<table>
<tbody>
<tr template="" repeat="{{ lineNumber in lineNumbers }}">
<td style="{{ styleForHits(script.lines[lineNumber].hits) }}"><span> </span></td>
<td style="font-family: consolas, courier, monospace;font-size: 1em;line-height: 1.2em;white-space: nowrap;">{{script.lines[lineNumber].line}}</td>
<td>&nbsp;</td>
<td width="99%" style="font-family: consolas, courier, monospace;font-size: 1em;line-height: 1.2em;white-space: pre;">{{script.lines[lineNumber].text}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
</polymer-element>
<polymer-element name="script-ref" extends="service-ref">
<template>
@ -4078,6 +4115,11 @@ hr {
<div class="content">
<eval-box callback="{{ eval }}"></eval-box>
</div>
<hr>
<script-inset script="{{ cls.script }}" pos="{{ cls.tokenPos }}" endpos="{{ cls.endTokenPos }}">
</script-inset>
<br><br><br><br>
<br><br><br><br>
</template>
@ -6221,42 +6263,6 @@ hr {
<polymer-element name="script-inset" extends="observatory-element">
<template>
<style>
.sourceInset {
padding-left: 15%;
padding-right: 15%;
}
.grayBox {
width: 100%;
background-color: #f5f5f5;
border: 1px solid #ccc;
padding: 10px;
}
</style>
<div class="sourceInset">
<content></content>
<div class="grayBox">
<table>
<tbody>
<tr template="" repeat="{{ lineNumber in lineNumbers }}">
<td style="{{ styleForHits(script.lines[lineNumber].hits) }}"><span> </span></td>
<td style="font-family: consolas, courier, monospace;font-size: 1em;line-height: 1.2em;white-space: nowrap;">{{script.lines[lineNumber].line}}</td>
<td>&nbsp;</td>
<td width="99%" style="font-family: consolas, courier, monospace;font-size: 1em;line-height: 1.2em;white-space: pre;">{{script.lines[lineNumber].text}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
</polymer-element>
<polymer-element name="function-view" extends="observatory-element">
<template>
<style>
@ -17591,4 +17597,4 @@ hr {
<observatory-application></observatory-application>
<script type="application/dart" src="index.html_bootstrap.dart"></script><script src="packages/browser/dart.js"></script></body></html>
<script src="index.html_bootstrap.dart.js" async=""></script></body></html>

View file

@ -1 +1 @@
{"experimental_bootstrap":false,"script_ids":[["observatory","lib/src/elements/curly_block.dart"],["observatory","lib/src/elements/observatory_element.dart"],["observatory","lib/src/elements/service_ref.dart"],["observatory","lib/src/elements/instance_ref.dart"],["observatory","lib/src/elements/action_link.dart"],["observatory","lib/src/elements/nav_bar.dart"],["observatory","lib/src/elements/breakpoint_list.dart"],["observatory","lib/src/elements/class_ref.dart"],["observatory","lib/src/elements/class_tree.dart"],["observatory","lib/src/elements/eval_box.dart"],["observatory","lib/src/elements/eval_link.dart"],["observatory","lib/src/elements/field_ref.dart"],["observatory","lib/src/elements/function_ref.dart"],["observatory","lib/src/elements/library_ref.dart"],["observatory","lib/src/elements/script_ref.dart"],["observatory","lib/src/elements/class_view.dart"],["observatory","lib/src/elements/code_ref.dart"],["observatory","lib/src/elements/code_view.dart"],["observatory","lib/src/elements/error_view.dart"],["observatory","lib/src/elements/field_view.dart"],["observatory","lib/src/elements/stack_frame.dart"],["observatory","lib/src/elements/flag_list.dart"],["observatory","lib/src/elements/script_inset.dart"],["observatory","lib/src/elements/function_view.dart"],["observatory","lib/src/elements/heap_map.dart"],["observatory","lib/src/elements/io_view.dart"],["observatory","lib/src/elements/isolate_ref.dart"],["observatory","lib/src/elements/isolate_summary.dart"],["observatory","lib/src/elements/isolate_view.dart"],["observatory","lib/src/elements/instance_view.dart"],["observatory","lib/src/elements/json_view.dart"],["observatory","lib/src/elements/library_view.dart"],["observatory","lib/src/elements/heap_profile.dart"],["observatory","lib/src/elements/sliding_checkbox.dart"],["observatory","lib/src/elements/isolate_profile.dart"],["observatory","lib/src/elements/script_view.dart"],["observatory","lib/src/elements/stack_trace.dart"],["observatory","lib/src/elements/vm_view.dart"],["observatory","lib/src/elements/service_view.dart"],["observatory","lib/src/elements/observatory_application.dart"],["observatory","lib/src/elements/service_exception_view.dart"],["observatory","lib/src/elements/service_error_view.dart"],["observatory","lib/src/elements/vm_connect.dart"],["observatory","lib/src/elements/vm_ref.dart"],["observatory","web/main.dart"]]}
{"experimental_bootstrap":false,"script_ids":[["observatory","lib/src/elements/curly_block.dart"],["observatory","lib/src/elements/observatory_element.dart"],["observatory","lib/src/elements/service_ref.dart"],["observatory","lib/src/elements/instance_ref.dart"],["observatory","lib/src/elements/action_link.dart"],["observatory","lib/src/elements/nav_bar.dart"],["observatory","lib/src/elements/breakpoint_list.dart"],["observatory","lib/src/elements/class_ref.dart"],["observatory","lib/src/elements/class_tree.dart"],["observatory","lib/src/elements/eval_box.dart"],["observatory","lib/src/elements/eval_link.dart"],["observatory","lib/src/elements/field_ref.dart"],["observatory","lib/src/elements/function_ref.dart"],["observatory","lib/src/elements/library_ref.dart"],["observatory","lib/src/elements/script_inset.dart"],["observatory","lib/src/elements/script_ref.dart"],["observatory","lib/src/elements/class_view.dart"],["observatory","lib/src/elements/code_ref.dart"],["observatory","lib/src/elements/code_view.dart"],["observatory","lib/src/elements/error_view.dart"],["observatory","lib/src/elements/field_view.dart"],["observatory","lib/src/elements/stack_frame.dart"],["observatory","lib/src/elements/flag_list.dart"],["observatory","lib/src/elements/function_view.dart"],["observatory","lib/src/elements/heap_map.dart"],["observatory","lib/src/elements/io_view.dart"],["observatory","lib/src/elements/isolate_ref.dart"],["observatory","lib/src/elements/isolate_summary.dart"],["observatory","lib/src/elements/isolate_view.dart"],["observatory","lib/src/elements/instance_view.dart"],["observatory","lib/src/elements/json_view.dart"],["observatory","lib/src/elements/library_view.dart"],["observatory","lib/src/elements/heap_profile.dart"],["observatory","lib/src/elements/sliding_checkbox.dart"],["observatory","lib/src/elements/isolate_profile.dart"],["observatory","lib/src/elements/script_view.dart"],["observatory","lib/src/elements/stack_trace.dart"],["observatory","lib/src/elements/vm_view.dart"],["observatory","lib/src/elements/service_view.dart"],["observatory","lib/src/elements/observatory_application.dart"],["observatory","lib/src/elements/service_exception_view.dart"],["observatory","lib/src/elements/service_error_view.dart"],["observatory","lib/src/elements/vm_connect.dart"],["observatory","lib/src/elements/vm_ref.dart"],["observatory","web/main.dart"]]}

File diff suppressed because one or more lines are too long

View file

@ -2496,6 +2496,7 @@ hr {
<polymer-element name="eval-box" extends="observatory-element">
<template>
<style>
@ -3404,6 +3405,42 @@ hr {
<polymer-element name="script-inset" extends="observatory-element">
<template>
<style>
.sourceInset {
padding-left: 15%;
padding-right: 15%;
}
.grayBox {
width: 100%;
background-color: #f5f5f5;
border: 1px solid #ccc;
padding: 10px;
}
</style>
<div class="sourceInset">
<content></content>
<div class="grayBox">
<table>
<tbody>
<tr template="" repeat="{{ lineNumber in lineNumbers }}">
<td style="{{ styleForHits(script.lines[lineNumber].hits) }}"><span> </span></td>
<td style="font-family: consolas, courier, monospace;font-size: 1em;line-height: 1.2em;white-space: nowrap;">{{script.lines[lineNumber].line}}</td>
<td>&nbsp;</td>
<td width="99%" style="font-family: consolas, courier, monospace;font-size: 1em;line-height: 1.2em;white-space: pre;">{{script.lines[lineNumber].text}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
</polymer-element>
<polymer-element name="script-ref" extends="service-ref">
<template>
@ -4078,6 +4115,11 @@ hr {
<div class="content">
<eval-box callback="{{ eval }}"></eval-box>
</div>
<hr>
<script-inset script="{{ cls.script }}" pos="{{ cls.tokenPos }}" endpos="{{ cls.endTokenPos }}">
</script-inset>
<br><br><br><br>
<br><br><br><br>
</template>
@ -6221,42 +6263,6 @@ hr {
<polymer-element name="script-inset" extends="observatory-element">
<template>
<style>
.sourceInset {
padding-left: 15%;
padding-right: 15%;
}
.grayBox {
width: 100%;
background-color: #f5f5f5;
border: 1px solid #ccc;
padding: 10px;
}
</style>
<div class="sourceInset">
<content></content>
<div class="grayBox">
<table>
<tbody>
<tr template="" repeat="{{ lineNumber in lineNumbers }}">
<td style="{{ styleForHits(script.lines[lineNumber].hits) }}"><span> </span></td>
<td style="font-family: consolas, courier, monospace;font-size: 1em;line-height: 1.2em;white-space: nowrap;">{{script.lines[lineNumber].line}}</td>
<td>&nbsp;</td>
<td width="99%" style="font-family: consolas, courier, monospace;font-size: 1em;line-height: 1.2em;white-space: pre;">{{script.lines[lineNumber].text}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
</polymer-element>
<polymer-element name="function-view" extends="observatory-element">
<template>
<style>
@ -17591,4 +17597,4 @@ hr {
<observatory-application devtools="true"></observatory-application>
<script type="application/dart" src="index_devtools.html_bootstrap.dart"></script><script src="packages/browser/dart.js"></script></body></html>
<script src="index_devtools.html_bootstrap.dart.js" async=""></script></body></html>

View file

@ -1 +1 @@
{"experimental_bootstrap":false,"script_ids":[["observatory","lib/src/elements/curly_block.dart"],["observatory","lib/src/elements/observatory_element.dart"],["observatory","lib/src/elements/service_ref.dart"],["observatory","lib/src/elements/instance_ref.dart"],["observatory","lib/src/elements/action_link.dart"],["observatory","lib/src/elements/nav_bar.dart"],["observatory","lib/src/elements/breakpoint_list.dart"],["observatory","lib/src/elements/class_ref.dart"],["observatory","lib/src/elements/class_tree.dart"],["observatory","lib/src/elements/eval_box.dart"],["observatory","lib/src/elements/eval_link.dart"],["observatory","lib/src/elements/field_ref.dart"],["observatory","lib/src/elements/function_ref.dart"],["observatory","lib/src/elements/library_ref.dart"],["observatory","lib/src/elements/script_ref.dart"],["observatory","lib/src/elements/class_view.dart"],["observatory","lib/src/elements/code_ref.dart"],["observatory","lib/src/elements/code_view.dart"],["observatory","lib/src/elements/error_view.dart"],["observatory","lib/src/elements/field_view.dart"],["observatory","lib/src/elements/stack_frame.dart"],["observatory","lib/src/elements/flag_list.dart"],["observatory","lib/src/elements/script_inset.dart"],["observatory","lib/src/elements/function_view.dart"],["observatory","lib/src/elements/heap_map.dart"],["observatory","lib/src/elements/io_view.dart"],["observatory","lib/src/elements/isolate_ref.dart"],["observatory","lib/src/elements/isolate_summary.dart"],["observatory","lib/src/elements/isolate_view.dart"],["observatory","lib/src/elements/instance_view.dart"],["observatory","lib/src/elements/json_view.dart"],["observatory","lib/src/elements/library_view.dart"],["observatory","lib/src/elements/heap_profile.dart"],["observatory","lib/src/elements/sliding_checkbox.dart"],["observatory","lib/src/elements/isolate_profile.dart"],["observatory","lib/src/elements/script_view.dart"],["observatory","lib/src/elements/stack_trace.dart"],["observatory","lib/src/elements/vm_view.dart"],["observatory","lib/src/elements/service_view.dart"],["observatory","lib/src/elements/observatory_application.dart"],["observatory","lib/src/elements/service_exception_view.dart"],["observatory","lib/src/elements/service_error_view.dart"],["observatory","lib/src/elements/vm_connect.dart"],["observatory","lib/src/elements/vm_ref.dart"],["observatory","web/main.dart"]]}
{"experimental_bootstrap":false,"script_ids":[["observatory","lib/src/elements/curly_block.dart"],["observatory","lib/src/elements/observatory_element.dart"],["observatory","lib/src/elements/service_ref.dart"],["observatory","lib/src/elements/instance_ref.dart"],["observatory","lib/src/elements/action_link.dart"],["observatory","lib/src/elements/nav_bar.dart"],["observatory","lib/src/elements/breakpoint_list.dart"],["observatory","lib/src/elements/class_ref.dart"],["observatory","lib/src/elements/class_tree.dart"],["observatory","lib/src/elements/eval_box.dart"],["observatory","lib/src/elements/eval_link.dart"],["observatory","lib/src/elements/field_ref.dart"],["observatory","lib/src/elements/function_ref.dart"],["observatory","lib/src/elements/library_ref.dart"],["observatory","lib/src/elements/script_inset.dart"],["observatory","lib/src/elements/script_ref.dart"],["observatory","lib/src/elements/class_view.dart"],["observatory","lib/src/elements/code_ref.dart"],["observatory","lib/src/elements/code_view.dart"],["observatory","lib/src/elements/error_view.dart"],["observatory","lib/src/elements/field_view.dart"],["observatory","lib/src/elements/stack_frame.dart"],["observatory","lib/src/elements/flag_list.dart"],["observatory","lib/src/elements/function_view.dart"],["observatory","lib/src/elements/heap_map.dart"],["observatory","lib/src/elements/io_view.dart"],["observatory","lib/src/elements/isolate_ref.dart"],["observatory","lib/src/elements/isolate_summary.dart"],["observatory","lib/src/elements/isolate_view.dart"],["observatory","lib/src/elements/instance_view.dart"],["observatory","lib/src/elements/json_view.dart"],["observatory","lib/src/elements/library_view.dart"],["observatory","lib/src/elements/heap_profile.dart"],["observatory","lib/src/elements/sliding_checkbox.dart"],["observatory","lib/src/elements/isolate_profile.dart"],["observatory","lib/src/elements/script_view.dart"],["observatory","lib/src/elements/stack_trace.dart"],["observatory","lib/src/elements/vm_view.dart"],["observatory","lib/src/elements/service_view.dart"],["observatory","lib/src/elements/observatory_application.dart"],["observatory","lib/src/elements/service_exception_view.dart"],["observatory","lib/src/elements/service_error_view.dart"],["observatory","lib/src/elements/vm_connect.dart"],["observatory","lib/src/elements/vm_ref.dart"],["observatory","web/main.dart"]]}

File diff suppressed because one or more lines are too long

View file

@ -8,6 +8,7 @@
<link rel="import" href="library_ref.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="script_inset.html">
<link rel="import" href="script_ref.html">
<polymer-element name="class-view" extends="observatory-element">
@ -186,6 +187,11 @@
<div class="content">
<eval-box callback="{{ eval }}"></eval-box>
</div>
<hr>
<script-inset script="{{ cls.script }}" pos="{{ cls.tokenPos }}" endPos="{{ cls.endTokenPos }}">
</script-inset>
<br><br><br><br>
<br><br><br><br>
</template>

View file

@ -8,6 +8,7 @@
<link rel="import" href="library_ref.html">
<link rel="import" href="nav_bar.html">
<link rel="import" href="observatory_element.html">
<link rel="import" href="script_inset.html">
<link rel="import" href="script_ref.html">
<polymer-element name="class-view" extends="observatory-element">
@ -186,6 +187,11 @@
<div class="content">
<eval-box callback="{{ eval }}"></eval-box>
</div>
<hr>
<script-inset script="{{ cls.script }}" pos="{{ cls.tokenPos }}" endPos="{{ cls.endTokenPos }}">
</script-inset>
<br><br><br><br>
<br><br><br><br>
</template>

View file

@ -1124,6 +1124,7 @@ class Class extends ServiceObject with Coverage {
@observable bool isImplemented;
@observable int tokenPos;
@observable int endTokenPos;
@observable ServiceMap error;
@ -1177,6 +1178,7 @@ class Class extends ServiceObject with Coverage {
isImplemented = map['implemented'];
tokenPos = map['tokenPos'];
endTokenPos = map['endTokenPos'];
subClasses.clear();
subClasses.addAll(map['subclasses']);

View file

@ -3252,6 +3252,32 @@ void Class::set_token_pos(intptr_t token_pos) const {
}
intptr_t Class::ComputeEndTokenPos() const {
// Return the begin token for synthetic classes.
if (IsSignatureClass() || IsMixinApplication() || IsTopLevel()) {
return token_pos();
}
const Script& scr = Script::Handle(script());
ASSERT(!scr.IsNull());
const TokenStream& tkns = TokenStream::Handle(scr.tokens());
TokenStream::Iterator tkit(
tkns, token_pos(), TokenStream::Iterator::kNoNewlines);
intptr_t level = 0;
while (tkit.CurrentTokenKind() != Token::kEOS) {
if (tkit.CurrentTokenKind() == Token::kLBRACE) {
level++;
} else if (tkit.CurrentTokenKind() == Token::kRBRACE) {
if (--level == 0) {
return tkit.CurrentPosition();
}
}
tkit.Advance();
}
UNREACHABLE();
return 0;
}
void Class::set_is_implemented() const {
set_state_bits(ImplementedBit::update(true, raw_ptr()->state_bits_));
}
@ -4008,6 +4034,7 @@ void Class::PrintJSONImpl(JSONStream* stream, bool ref) const {
if (!script.IsNull()) {
jsobj.AddProperty("script", script);
jsobj.AddProperty("tokenPos", token_pos());
jsobj.AddProperty("endTokenPos", ComputeEndTokenPos());
}
{
JSONArray interfaces_array(&jsobj, "interfaces");

View file

@ -748,6 +748,8 @@ class Class : public Object {
intptr_t token_pos() const { return raw_ptr()->token_pos_; }
void set_token_pos(intptr_t value) const;
intptr_t ComputeEndTokenPos() const;
// This class represents the signature class of a closure function if
// signature_function() is not null.
// The associated function may be a closure function (with code) or a

View file

@ -221,6 +221,35 @@ TEST_CASE(GenerateExactSource) {
}
TEST_CASE(Class_ComputeEndTokenPos) {
const char* kScript =
"\n"
"class A {\n"
" /**\n"
" * Description of foo().\n"
" */\n"
" foo(a) { return '''\"}'''; }\n"
" // }\n"
" var bar = '\\'}';\n"
" var baz = \"${foo('}')}\";\n"
"}\n";
Dart_Handle lib_h = TestCase::LoadTestScript(kScript, NULL);
EXPECT_VALID(lib_h);
Library& lib = Library::Handle();
lib ^= Api::UnwrapHandle(lib_h);
EXPECT(!lib.IsNull());
const Class& cls = Class::Handle(
lib.LookupClass(String::Handle(String::New("A"))));
EXPECT(!cls.IsNull());
const intptr_t end_token_pos = cls.ComputeEndTokenPos();
const Script& scr = Script::Handle(cls.script());
intptr_t line;
intptr_t col;
scr.GetTokenLocation(end_token_pos, &line, &col);
EXPECT(line == 10 && col == 1);
}
TEST_CASE(InstanceClass) {
// Allocate the class first.
String& class_name = String::Handle(Symbols::New("EmptyClass"));

View file

@ -840,6 +840,8 @@ TEST_CASE(Service_Classes) {
ExpectSubstringF(handler.msg(),
"\"id\":\"classes\\/%" Pd "\",\"name\":\"A\",", cid);
ExpectSubstringF(handler.msg(), "\"allocationStats\":");
ExpectSubstringF(handler.msg(), "\"tokenPos\":");
ExpectSubstringF(handler.msg(), "\"endTokenPos\":");
// Evaluate an expression from class A.
service_msg = EvalF(h_lib,