Refactor VM service IDs:
- IDs are strings which can be concatenated together like paths. - Isolate ID is now "/isolates/XXX" - Function, field, class, library, and script IDs are now stable. - Introduce <type-ref> tags. R=turnidge@google.com Review URL: https://codereview.chromium.org//98253009 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@31358 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
@@ -29,7 +29,15 @@
|
||||
</template>
|
||||
</template>
|
||||
|
||||
</polymer-element><polymer-element name="error-view" extends="observatory-element">
|
||||
</polymer-element><polymer-element name="service-ref" extends="observatory-element">
|
||||
|
||||
</polymer-element><polymer-element name="class-ref" extends="service-ref">
|
||||
<template>
|
||||
<a href="{{ url }}">{{ name }}</a>
|
||||
</template>
|
||||
|
||||
</polymer-element>
|
||||
<polymer-element name="error-view" extends="observatory-element">
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
@@ -48,34 +56,42 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</polymer-element><polymer-element name="field-ref" extends="observatory-element">
|
||||
</polymer-element><polymer-element name="field-ref" extends="service-ref">
|
||||
<template>
|
||||
<div>
|
||||
<template if="{{ field['final'] }}"> final </template>
|
||||
<template if="{{ field['const'] }}"> const </template>
|
||||
<template if="{{ (field['declared_type']['name'] == 'dynamic' && !field['final'] && !field['const']) }}">
|
||||
<template if="{{ ref['final'] }}"> final </template>
|
||||
<template if="{{ ref['const'] }}"> const </template>
|
||||
<template if="{{ (ref['declared_type']['name'] == 'dynamic' && !ref['final'] && !ref['const']) }}">
|
||||
var
|
||||
</template>
|
||||
<template if="{{ (field['declared_type']['name'] != 'dynamic') }}">
|
||||
<a href="{{ app.locationManager.currentIsolateClassLink(field['declared_type']['id']) }}">
|
||||
{{ field['declared_type']['user_name'] }} </a>
|
||||
<template if="{{ (ref['declared_type']['name'] != 'dynamic') }}">
|
||||
<class-ref app="{{ app }}" ref="{{ ref['declared_type'] }}"></class-ref>
|
||||
</template>
|
||||
<a href="{{ app.locationManager.currentIsolateObjectLink(field['id'])}}">
|
||||
{{ field['user_name'] }} </a>
|
||||
<a href="{{ url }}">{{ name }}</a>
|
||||
</div>
|
||||
</template> </polymer-element><polymer-element name="instance-ref" extends="observatory-element">
|
||||
</template> </polymer-element><polymer-element name="function-ref" extends="service-ref">
|
||||
<template>
|
||||
<a href="{{ url }}">{{ name }}</a>
|
||||
</template>
|
||||
|
||||
</polymer-element><polymer-element name="instance-ref" extends="service-ref">
|
||||
<template>
|
||||
<div>
|
||||
<template if="{{ (instance['type'] == 'null') }}">
|
||||
<template if="{{ (ref['type'] == 'null') }}">
|
||||
{{ "null" }}
|
||||
</template>
|
||||
<template if="{{ (instance['type'] != 'null') }}">
|
||||
<a href="{{ app.locationManager.currentIsolateObjectLink(instance['id'])}}">
|
||||
{{ instance['preview'] }}
|
||||
</a>
|
||||
<template if="{{ (ref['type'] != 'null') }}">
|
||||
<a href="{{ url }}">{{ name }} </a>
|
||||
</template>
|
||||
</div>
|
||||
</template> </polymer-element><polymer-element name="class-view" extends="observatory-element">
|
||||
</template>
|
||||
|
||||
</polymer-element><polymer-element name="library-ref" extends="service-ref">
|
||||
<template>
|
||||
<a href="{{ url }}">{{ name }}</a>
|
||||
</template>
|
||||
|
||||
</polymer-element><polymer-element name="class-view" extends="observatory-element">
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
@@ -84,13 +100,9 @@
|
||||
class <strong>{{ cls['user_name'] }}</strong>
|
||||
<template if="{{ cls['super']['type'] != 'Null' }}">
|
||||
extends
|
||||
<a href="{{ app.locationManager.currentIsolateClassLink(cls['super']['id'])}}">
|
||||
{{ cls['super']['user_name'] }}
|
||||
</a>
|
||||
<class-ref app="{{ app }}" ref="{{ cls['super'] }}"></class-ref>
|
||||
</template>
|
||||
<a class="pull-right" href="{{ app.locationManager.currentIsolateObjectLink(cls['library']['id'])}}">
|
||||
{{ cls['library']['name'] }}
|
||||
</a>
|
||||
<library-ref app="{{ app }}" ref="{{ cls['library'] }}"></library-ref>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<table class="table table-hover">
|
||||
@@ -120,8 +132,8 @@
|
||||
<table class="table table-hover">
|
||||
<tbody>
|
||||
<tr template="" repeat="{{ field in cls['fields'] }}">
|
||||
<td><field-ref app="{{ app }}" field="{{ field }}"></field-ref></td>
|
||||
<td><instance-ref app="{{ app }}" instance="{{ field['value'] }}"></instance-ref></td>
|
||||
<td><field-ref app="{{ app }}" ref="{{ field }}"></field-ref></td>
|
||||
<td><instance-ref app="{{ app }}" ref="{{ field['value'] }}"></instance-ref></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -135,8 +147,8 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr template="" repeat="{{ function in cls['functions'] }}">
|
||||
<td><a href="{{ app.locationManager.currentIsolateObjectLink(function['id'])}}">{{ function['user_name'] }}</a></td>
|
||||
<td><a href="{{ app.locationManager.currentIsolateObjectLink(function['id'])}}">{{ function['name'] }}</a></td>
|
||||
<td><function-ref app="{{ app }}" ref="{{ function }}"></function-ref></td>
|
||||
<td><function-ref app="{{ app }}" ref="{{ function }}" internal=""></function-ref></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -150,6 +162,12 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</polymer-element>
|
||||
<polymer-element name="code-ref" extends="service-ref">
|
||||
<template>
|
||||
<a href="{{ url }}">{{ name }}</a>
|
||||
</template>
|
||||
|
||||
</polymer-element><polymer-element name="disassembly-entry" extends="observatory-element">
|
||||
<template>
|
||||
<div class="row">
|
||||
@@ -174,9 +192,7 @@
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<div class="{{ cssPanelClass }}">
|
||||
<div class="panel-heading">
|
||||
<a href="{{ app.locationManager.currentIsolateObjectLink(code['function']['id'])}}">
|
||||
{{ code['function']['user_name'] }} ({{ code['function']['name'] }})
|
||||
</a>
|
||||
<function-ref app="{{ app }}" ref="{{ code['function'] }}"></function-ref>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
@@ -215,10 +231,8 @@
|
||||
<template if="{{ field['static'] }}">static</template>
|
||||
<template if="{{ field['final'] }}">final</template>
|
||||
<template if="{{ field['const'] }}">const</template>
|
||||
{{ field['user_name'] }} ({{ field['name'] }})
|
||||
<a class="pull-right" href="{{ app.locationManager.currentIsolateClassLink(field['class']['id'])}}">
|
||||
{{ field['class']['user_name'] }}
|
||||
</a>
|
||||
{{ field['user_name'] }} ({{ field['name'] }})
|
||||
<class-ref app="{{ app }}" ref="{{ field['class'] }}"></class-ref>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<template if="{{ field['guard_class'] == 'dynamic'}}">
|
||||
@@ -227,9 +241,9 @@
|
||||
assigned a single type, performance may improve.
|
||||
</div>
|
||||
</template>
|
||||
<template if="{{ field['guard_class'] != 'dynamic'}}">
|
||||
<template if="{{ (field['guard_class'] != 'dynamic') && (field['guard_class'] != 'unknown') }}">
|
||||
<div class="alert alert-success">Field has monomorphic type</div>
|
||||
<template if="{{ (field['guard_class'] != 'dynamic') &&
|
||||
<template if="{{ (field['guard_class'] != 'dynamic') &&
|
||||
field['guard_nullable'] }}">
|
||||
<div class="alert alert-info">
|
||||
Field has been assigned null. If a field is never assigned null,
|
||||
@@ -237,9 +251,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<blockquote>
|
||||
<a href="{{ app.locationManager.currentIsolateClassLink(field['guard_class']['id'])}}">
|
||||
{{ field['guard_class']['user_name'] }}
|
||||
</a>
|
||||
<class-ref app="{{ app }}" ref="{{ field['guard_class'] }}"></class-ref>
|
||||
</blockquote>
|
||||
</template>
|
||||
</div>
|
||||
@@ -254,15 +266,13 @@
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<div class="panel panel-warning">
|
||||
<div class="panel-heading">
|
||||
{{ function['user_name'] }} ({{ function['name'] }})
|
||||
<a class="pull-right" href="{{ app.locationManager.currentIsolateClassLink(function['class']['id'])}}">
|
||||
{{ function['class']['name'] }}
|
||||
</a>
|
||||
{{ function['user_name'] }} ({{ function['name'] }})
|
||||
<class-ref app="{{ app }}" ref="{{ function['class'] }}"></class-ref>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div>
|
||||
<a class="btn btn-primary" href="{{ app.locationManager.currentIsolateObjectLink(function['code']['id'])}}">Current Code</a>
|
||||
<a class="btn btn-info" href="{{ app.locationManager.currentIsolateObjectLink(function['unoptimized_code']['id'])}}">Unoptimized Code</a>
|
||||
<code-ref app="{{ app }}" ref="{{ function['code'] }}"></code-ref>
|
||||
<code-ref app="{{ app }}" ref="{{ function['unoptimized_code'] }}"></code-ref>
|
||||
</div>
|
||||
<table class="table table-hover">
|
||||
<tbody>
|
||||
@@ -337,12 +347,10 @@
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<div class="panel panel-warning">
|
||||
<div class="panel panel-warning">
|
||||
<div class="panel-heading">
|
||||
Instance of
|
||||
<a href="{{ app.locationManager.currentIsolateClassLink(instance['class']['id'])}}">
|
||||
{{ instance['class']['user_name'] }}
|
||||
</a>
|
||||
<class-ref app="{{ app }}" ref="{{ instance['class'] }}"></class-ref>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<template if="{{ instance['error'] == null }}">
|
||||
@@ -357,8 +365,8 @@
|
||||
<table class="table table-hover">
|
||||
<tbody>
|
||||
<tr template="" repeat="{{ field in instance['fields'] }}">
|
||||
<td><field-ref app="{{ app }}" field="{{ field }}"></field-ref></td>
|
||||
<td><instance-ref app="{{ app }}" instance="{{ field['value'] }}"></instance-ref></td>
|
||||
<td><field-ref app="{{ app }}" ref="{{ field }}"></field-ref></td>
|
||||
<td><instance-ref app="{{ app }}" ref="{{ field['value'] }}"></instance-ref></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -372,7 +380,8 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</polymer-element><polymer-element name="json-view" extends="observatory-element">
|
||||
</polymer-element>
|
||||
<polymer-element name="json-view" extends="observatory-element">
|
||||
<template>
|
||||
<template bind="" if="{{ valueType == 'Primitive' }}">
|
||||
<span>{{primitiveString}}</span>
|
||||
@@ -401,6 +410,12 @@
|
||||
</template>
|
||||
</template>
|
||||
|
||||
</polymer-element>
|
||||
<polymer-element name="script-ref" extends="service-ref">
|
||||
<template>
|
||||
<a href="{{ url }}">{{ name }}</a>
|
||||
</template>
|
||||
|
||||
</polymer-element><polymer-element name="library-view" extends="observatory-element">
|
||||
<template>
|
||||
<div class="alert alert-success">Library {{ library['name'] }}</div>
|
||||
@@ -412,7 +427,7 @@
|
||||
{{ script['kind'] }}
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{ app.locationManager.currentIsolateScriptLink(script['id'], script['name']) }}">{{ script['name'] }}</a>
|
||||
<script-ref app="{{ app }}" ref="{{ script }}"></script-ref>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -422,9 +437,7 @@
|
||||
<tbody>
|
||||
<tr template="" repeat="{{ lib in library['libraries'] }}">
|
||||
<td>
|
||||
<a href="{{ app.locationManager.currentIsolateObjectLink(lib['id'])}}">
|
||||
{{ lib['url'] }}
|
||||
</a>
|
||||
<library-ref app="{{ app }}" ref="{{ lib }}"></library-ref>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -433,8 +446,8 @@
|
||||
<table class="table table-hover">
|
||||
<tbody>
|
||||
<tr template="" repeat="{{ variable in library['variables'] }}">
|
||||
<td><field-ref app="{{ app }}" field="{{ variable }}"></field-ref></td>
|
||||
<td><instance-ref app="{{ app }}" instance="{{ variable['value'] }}"></instance-ref></td>
|
||||
<td><field-ref app="{{ app }}" ref="{{ variable }}"></field-ref></td>
|
||||
<td><instance-ref app="{{ app }}" ref="{{ variable['value'] }}"></instance-ref></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -443,9 +456,7 @@
|
||||
<tbody>
|
||||
<tr template="" repeat="{{ func in library['functions'] }}">
|
||||
<td>
|
||||
<a href="{{ app.locationManager.currentIsolateObjectLink(func['id'])}}">
|
||||
{{ func['user_name'] }}
|
||||
</a>
|
||||
<function-ref app="{{ app }}" ref="{{ func }}"></function-ref>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -461,14 +472,10 @@
|
||||
<tbody>
|
||||
<tr template="" repeat="{{ cls in library['classes'] }}">
|
||||
<td>
|
||||
<a href="{{ app.locationManager.currentIsolateClassLink(cls['id']) }}">
|
||||
{{ cls['user_name'] }}
|
||||
</a>
|
||||
<class-ref app="{{ app }}" ref="{{ cls }}"></class-ref>
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{ app.locationManager.currentIsolateClassLink(cls['id']) }}">
|
||||
{{ cls['name'] }}
|
||||
</a>
|
||||
<class-ref app="{{ app }}" ref="{{ cls }}" internal=""></class-ref>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -506,15 +513,15 @@
|
||||
<tr>
|
||||
<th>Depth</th>
|
||||
<th>Function</th>
|
||||
<th>Url</th>
|
||||
<th>Script</th>
|
||||
<th>Line</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr template="" repeat="{{ frame in trace['members'] }}">
|
||||
<td>{{$index}}</td>
|
||||
<td><a href="{{app.locationManager.currentIsolateObjectLink(frame['function']['id'])}}">{{ frame['name'] }}</a></td>
|
||||
<td>{{ frame['url'] }}</td>
|
||||
<td><function-ref app="{{ app }}" ref="{{ frame['function'] }}"></function-ref></td>
|
||||
<td><script-ref app="{{ app }}" ref="{{ frame['script'] }}"></script-ref></td>
|
||||
<td>{{ frame['line'] }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -588,7 +595,6 @@
|
||||
<a class="navbar-brand" href="">Observatory</a>
|
||||
</div>
|
||||
<div class="collapse navbar-collapse navbar-ex1-collapse">
|
||||
<input class="span2 pull-right navbar-form" placeholder="VM Address" type="text" value="{{ app.requestManager.prefix }}">
|
||||
</div>
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -29,7 +29,15 @@
|
||||
</template>
|
||||
</template>
|
||||
|
||||
</polymer-element><polymer-element name="error-view" extends="observatory-element">
|
||||
</polymer-element><polymer-element name="service-ref" extends="observatory-element">
|
||||
|
||||
</polymer-element><polymer-element name="class-ref" extends="service-ref">
|
||||
<template>
|
||||
<a href="{{ url }}">{{ name }}</a>
|
||||
</template>
|
||||
|
||||
</polymer-element>
|
||||
<polymer-element name="error-view" extends="observatory-element">
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
@@ -48,34 +56,42 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</polymer-element><polymer-element name="field-ref" extends="observatory-element">
|
||||
</polymer-element><polymer-element name="field-ref" extends="service-ref">
|
||||
<template>
|
||||
<div>
|
||||
<template if="{{ field['final'] }}"> final </template>
|
||||
<template if="{{ field['const'] }}"> const </template>
|
||||
<template if="{{ (field['declared_type']['name'] == 'dynamic' && !field['final'] && !field['const']) }}">
|
||||
<template if="{{ ref['final'] }}"> final </template>
|
||||
<template if="{{ ref['const'] }}"> const </template>
|
||||
<template if="{{ (ref['declared_type']['name'] == 'dynamic' && !ref['final'] && !ref['const']) }}">
|
||||
var
|
||||
</template>
|
||||
<template if="{{ (field['declared_type']['name'] != 'dynamic') }}">
|
||||
<a href="{{ app.locationManager.currentIsolateClassLink(field['declared_type']['id']) }}">
|
||||
{{ field['declared_type']['user_name'] }} </a>
|
||||
<template if="{{ (ref['declared_type']['name'] != 'dynamic') }}">
|
||||
<class-ref app="{{ app }}" ref="{{ ref['declared_type'] }}"></class-ref>
|
||||
</template>
|
||||
<a href="{{ app.locationManager.currentIsolateObjectLink(field['id'])}}">
|
||||
{{ field['user_name'] }} </a>
|
||||
<a href="{{ url }}">{{ name }}</a>
|
||||
</div>
|
||||
</template> </polymer-element><polymer-element name="instance-ref" extends="observatory-element">
|
||||
</template> </polymer-element><polymer-element name="function-ref" extends="service-ref">
|
||||
<template>
|
||||
<a href="{{ url }}">{{ name }}</a>
|
||||
</template>
|
||||
|
||||
</polymer-element><polymer-element name="instance-ref" extends="service-ref">
|
||||
<template>
|
||||
<div>
|
||||
<template if="{{ (instance['type'] == 'null') }}">
|
||||
<template if="{{ (ref['type'] == 'null') }}">
|
||||
{{ "null" }}
|
||||
</template>
|
||||
<template if="{{ (instance['type'] != 'null') }}">
|
||||
<a href="{{ app.locationManager.currentIsolateObjectLink(instance['id'])}}">
|
||||
{{ instance['preview'] }}
|
||||
</a>
|
||||
<template if="{{ (ref['type'] != 'null') }}">
|
||||
<a href="{{ url }}">{{ name }} </a>
|
||||
</template>
|
||||
</div>
|
||||
</template> </polymer-element><polymer-element name="class-view" extends="observatory-element">
|
||||
</template>
|
||||
|
||||
</polymer-element><polymer-element name="library-ref" extends="service-ref">
|
||||
<template>
|
||||
<a href="{{ url }}">{{ name }}</a>
|
||||
</template>
|
||||
|
||||
</polymer-element><polymer-element name="class-view" extends="observatory-element">
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
@@ -84,13 +100,9 @@
|
||||
class <strong>{{ cls['user_name'] }}</strong>
|
||||
<template if="{{ cls['super']['type'] != 'Null' }}">
|
||||
extends
|
||||
<a href="{{ app.locationManager.currentIsolateClassLink(cls['super']['id'])}}">
|
||||
{{ cls['super']['user_name'] }}
|
||||
</a>
|
||||
<class-ref app="{{ app }}" ref="{{ cls['super'] }}"></class-ref>
|
||||
</template>
|
||||
<a class="pull-right" href="{{ app.locationManager.currentIsolateObjectLink(cls['library']['id'])}}">
|
||||
{{ cls['library']['name'] }}
|
||||
</a>
|
||||
<library-ref app="{{ app }}" ref="{{ cls['library'] }}"></library-ref>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<table class="table table-hover">
|
||||
@@ -120,8 +132,8 @@
|
||||
<table class="table table-hover">
|
||||
<tbody>
|
||||
<tr template="" repeat="{{ field in cls['fields'] }}">
|
||||
<td><field-ref app="{{ app }}" field="{{ field }}"></field-ref></td>
|
||||
<td><instance-ref app="{{ app }}" instance="{{ field['value'] }}"></instance-ref></td>
|
||||
<td><field-ref app="{{ app }}" ref="{{ field }}"></field-ref></td>
|
||||
<td><instance-ref app="{{ app }}" ref="{{ field['value'] }}"></instance-ref></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -135,8 +147,8 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr template="" repeat="{{ function in cls['functions'] }}">
|
||||
<td><a href="{{ app.locationManager.currentIsolateObjectLink(function['id'])}}">{{ function['user_name'] }}</a></td>
|
||||
<td><a href="{{ app.locationManager.currentIsolateObjectLink(function['id'])}}">{{ function['name'] }}</a></td>
|
||||
<td><function-ref app="{{ app }}" ref="{{ function }}"></function-ref></td>
|
||||
<td><function-ref app="{{ app }}" ref="{{ function }}" internal=""></function-ref></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -150,6 +162,12 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</polymer-element>
|
||||
<polymer-element name="code-ref" extends="service-ref">
|
||||
<template>
|
||||
<a href="{{ url }}">{{ name }}</a>
|
||||
</template>
|
||||
|
||||
</polymer-element><polymer-element name="disassembly-entry" extends="observatory-element">
|
||||
<template>
|
||||
<div class="row">
|
||||
@@ -174,9 +192,7 @@
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<div class="{{ cssPanelClass }}">
|
||||
<div class="panel-heading">
|
||||
<a href="{{ app.locationManager.currentIsolateObjectLink(code['function']['id'])}}">
|
||||
{{ code['function']['user_name'] }} ({{ code['function']['name'] }})
|
||||
</a>
|
||||
<function-ref app="{{ app }}" ref="{{ code['function'] }}"></function-ref>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
@@ -215,10 +231,8 @@
|
||||
<template if="{{ field['static'] }}">static</template>
|
||||
<template if="{{ field['final'] }}">final</template>
|
||||
<template if="{{ field['const'] }}">const</template>
|
||||
{{ field['user_name'] }} ({{ field['name'] }})
|
||||
<a class="pull-right" href="{{ app.locationManager.currentIsolateClassLink(field['class']['id'])}}">
|
||||
{{ field['class']['user_name'] }}
|
||||
</a>
|
||||
{{ field['user_name'] }} ({{ field['name'] }})
|
||||
<class-ref app="{{ app }}" ref="{{ field['class'] }}"></class-ref>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<template if="{{ field['guard_class'] == 'dynamic'}}">
|
||||
@@ -227,9 +241,9 @@
|
||||
assigned a single type, performance may improve.
|
||||
</div>
|
||||
</template>
|
||||
<template if="{{ field['guard_class'] != 'dynamic'}}">
|
||||
<template if="{{ (field['guard_class'] != 'dynamic') && (field['guard_class'] != 'unknown') }}">
|
||||
<div class="alert alert-success">Field has monomorphic type</div>
|
||||
<template if="{{ (field['guard_class'] != 'dynamic') &&
|
||||
<template if="{{ (field['guard_class'] != 'dynamic') &&
|
||||
field['guard_nullable'] }}">
|
||||
<div class="alert alert-info">
|
||||
Field has been assigned null. If a field is never assigned null,
|
||||
@@ -237,9 +251,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<blockquote>
|
||||
<a href="{{ app.locationManager.currentIsolateClassLink(field['guard_class']['id'])}}">
|
||||
{{ field['guard_class']['user_name'] }}
|
||||
</a>
|
||||
<class-ref app="{{ app }}" ref="{{ field['guard_class'] }}"></class-ref>
|
||||
</blockquote>
|
||||
</template>
|
||||
</div>
|
||||
@@ -254,15 +266,13 @@
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<div class="panel panel-warning">
|
||||
<div class="panel-heading">
|
||||
{{ function['user_name'] }} ({{ function['name'] }})
|
||||
<a class="pull-right" href="{{ app.locationManager.currentIsolateClassLink(function['class']['id'])}}">
|
||||
{{ function['class']['name'] }}
|
||||
</a>
|
||||
{{ function['user_name'] }} ({{ function['name'] }})
|
||||
<class-ref app="{{ app }}" ref="{{ function['class'] }}"></class-ref>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div>
|
||||
<a class="btn btn-primary" href="{{ app.locationManager.currentIsolateObjectLink(function['code']['id'])}}">Current Code</a>
|
||||
<a class="btn btn-info" href="{{ app.locationManager.currentIsolateObjectLink(function['unoptimized_code']['id'])}}">Unoptimized Code</a>
|
||||
<code-ref app="{{ app }}" ref="{{ function['code'] }}"></code-ref>
|
||||
<code-ref app="{{ app }}" ref="{{ function['unoptimized_code'] }}"></code-ref>
|
||||
</div>
|
||||
<table class="table table-hover">
|
||||
<tbody>
|
||||
@@ -337,12 +347,10 @@
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<div class="panel panel-warning">
|
||||
<div class="panel panel-warning">
|
||||
<div class="panel-heading">
|
||||
Instance of
|
||||
<a href="{{ app.locationManager.currentIsolateClassLink(instance['class']['id'])}}">
|
||||
{{ instance['class']['user_name'] }}
|
||||
</a>
|
||||
<class-ref app="{{ app }}" ref="{{ instance['class'] }}"></class-ref>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<template if="{{ instance['error'] == null }}">
|
||||
@@ -357,8 +365,8 @@
|
||||
<table class="table table-hover">
|
||||
<tbody>
|
||||
<tr template="" repeat="{{ field in instance['fields'] }}">
|
||||
<td><field-ref app="{{ app }}" field="{{ field }}"></field-ref></td>
|
||||
<td><instance-ref app="{{ app }}" instance="{{ field['value'] }}"></instance-ref></td>
|
||||
<td><field-ref app="{{ app }}" ref="{{ field }}"></field-ref></td>
|
||||
<td><instance-ref app="{{ app }}" ref="{{ field['value'] }}"></instance-ref></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -372,7 +380,8 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</polymer-element><polymer-element name="json-view" extends="observatory-element">
|
||||
</polymer-element>
|
||||
<polymer-element name="json-view" extends="observatory-element">
|
||||
<template>
|
||||
<template bind="" if="{{ valueType == 'Primitive' }}">
|
||||
<span>{{primitiveString}}</span>
|
||||
@@ -401,6 +410,12 @@
|
||||
</template>
|
||||
</template>
|
||||
|
||||
</polymer-element>
|
||||
<polymer-element name="script-ref" extends="service-ref">
|
||||
<template>
|
||||
<a href="{{ url }}">{{ name }}</a>
|
||||
</template>
|
||||
|
||||
</polymer-element><polymer-element name="library-view" extends="observatory-element">
|
||||
<template>
|
||||
<div class="alert alert-success">Library {{ library['name'] }}</div>
|
||||
@@ -412,7 +427,7 @@
|
||||
{{ script['kind'] }}
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{ app.locationManager.currentIsolateScriptLink(script['id'], script['name']) }}">{{ script['name'] }}</a>
|
||||
<script-ref app="{{ app }}" ref="{{ script }}"></script-ref>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -422,9 +437,7 @@
|
||||
<tbody>
|
||||
<tr template="" repeat="{{ lib in library['libraries'] }}">
|
||||
<td>
|
||||
<a href="{{ app.locationManager.currentIsolateObjectLink(lib['id'])}}">
|
||||
{{ lib['url'] }}
|
||||
</a>
|
||||
<library-ref app="{{ app }}" ref="{{ lib }}"></library-ref>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -433,8 +446,8 @@
|
||||
<table class="table table-hover">
|
||||
<tbody>
|
||||
<tr template="" repeat="{{ variable in library['variables'] }}">
|
||||
<td><field-ref app="{{ app }}" field="{{ variable }}"></field-ref></td>
|
||||
<td><instance-ref app="{{ app }}" instance="{{ variable['value'] }}"></instance-ref></td>
|
||||
<td><field-ref app="{{ app }}" ref="{{ variable }}"></field-ref></td>
|
||||
<td><instance-ref app="{{ app }}" ref="{{ variable['value'] }}"></instance-ref></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -443,9 +456,7 @@
|
||||
<tbody>
|
||||
<tr template="" repeat="{{ func in library['functions'] }}">
|
||||
<td>
|
||||
<a href="{{ app.locationManager.currentIsolateObjectLink(func['id'])}}">
|
||||
{{ func['user_name'] }}
|
||||
</a>
|
||||
<function-ref app="{{ app }}" ref="{{ func }}"></function-ref>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -461,14 +472,10 @@
|
||||
<tbody>
|
||||
<tr template="" repeat="{{ cls in library['classes'] }}">
|
||||
<td>
|
||||
<a href="{{ app.locationManager.currentIsolateClassLink(cls['id']) }}">
|
||||
{{ cls['user_name'] }}
|
||||
</a>
|
||||
<class-ref app="{{ app }}" ref="{{ cls }}"></class-ref>
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{ app.locationManager.currentIsolateClassLink(cls['id']) }}">
|
||||
{{ cls['name'] }}
|
||||
</a>
|
||||
<class-ref app="{{ app }}" ref="{{ cls }}" internal=""></class-ref>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -506,15 +513,15 @@
|
||||
<tr>
|
||||
<th>Depth</th>
|
||||
<th>Function</th>
|
||||
<th>Url</th>
|
||||
<th>Script</th>
|
||||
<th>Line</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr template="" repeat="{{ frame in trace['members'] }}">
|
||||
<td>{{$index}}</td>
|
||||
<td><a href="{{app.locationManager.currentIsolateObjectLink(frame['function']['id'])}}">{{ frame['name'] }}</a></td>
|
||||
<td>{{ frame['url'] }}</td>
|
||||
<td><function-ref app="{{ app }}" ref="{{ frame['function'] }}"></function-ref></td>
|
||||
<td><script-ref app="{{ app }}" ref="{{ frame['script'] }}"></script-ref></td>
|
||||
<td>{{ frame['line'] }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -588,7 +595,6 @@
|
||||
<a class="navbar-brand" href="">Observatory</a>
|
||||
</div>
|
||||
<div class="collapse navbar-collapse navbar-ex1-collapse">
|
||||
<input class="span2 pull-right navbar-form" placeholder="VM Address" type="text" value="{{ app.requestManager.prefix }}">
|
||||
</div>
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
+24953
-22181
File diff suppressed because one or more lines are too long
@@ -2,24 +2,30 @@ library observatory_elements;
|
||||
|
||||
// Export elements.
|
||||
export 'package:observatory/src/observatory_elements/breakpoint_list.dart';
|
||||
export 'package:observatory/src/observatory_elements/class_ref.dart';
|
||||
export 'package:observatory/src/observatory_elements/class_view.dart';
|
||||
export 'package:observatory/src/observatory_elements/code_ref.dart';
|
||||
export 'package:observatory/src/observatory_elements/code_view.dart';
|
||||
export 'package:observatory/src/observatory_elements/collapsible_content.dart';
|
||||
export 'package:observatory/src/observatory_elements/error_view.dart';
|
||||
export 'package:observatory/src/observatory_elements/field_ref.dart';
|
||||
export 'package:observatory/src/observatory_elements/field_view.dart';
|
||||
export 'package:observatory/src/observatory_elements/function_ref.dart';
|
||||
export 'package:observatory/src/observatory_elements/function_view.dart';
|
||||
export 'package:observatory/src/observatory_elements/instance_ref.dart';
|
||||
export 'package:observatory/src/observatory_elements/instance_view.dart';
|
||||
export 'package:observatory/src/observatory_elements/isolate_list.dart';
|
||||
export 'package:observatory/src/observatory_elements/isolate_summary.dart';
|
||||
export 'package:observatory/src/observatory_elements/json_view.dart';
|
||||
export 'package:observatory/src/observatory_elements/library_ref.dart';
|
||||
export 'package:observatory/src/observatory_elements/library_view.dart';
|
||||
export 'package:observatory/src/observatory_elements/message_viewer.dart';
|
||||
export 'package:observatory/src/observatory_elements/navigation_bar.dart';
|
||||
export
|
||||
'package:observatory/src/observatory_elements/observatory_application.dart';
|
||||
export 'package:observatory/src/observatory_elements/response_viewer.dart';
|
||||
export 'package:observatory/src/observatory_elements/script_ref.dart';
|
||||
export 'package:observatory/src/observatory_elements/script_view.dart';
|
||||
export 'package:observatory/src/observatory_elements/service_ref.dart';
|
||||
export 'package:observatory/src/observatory_elements/source_view.dart';
|
||||
export 'package:observatory/src/observatory_elements/stack_trace.dart';
|
||||
|
||||
|
||||
@@ -2,18 +2,23 @@
|
||||
<html>
|
||||
<head>
|
||||
<link rel="import" href="src/observatory_elements/breakpoint_list.html">
|
||||
<link rel="import" href="src/observatory_elements/class_ref.html">
|
||||
<link rel="import" href="src/observatory_elements/class_view.html">
|
||||
<link rel="import" href="src/observatory_elements/code_ref.html">
|
||||
<link rel="import" href="src/observatory_elements/code_view.html">
|
||||
<link rel="import" href="src/observatory_elements/collapsible_content.html">
|
||||
<link rel="import" href="src/observatory_elements/disassembly_entry.html">
|
||||
<link rel="import" href="src/observatory_elements/error_view.html">
|
||||
<link rel="import" href="src/observatory_elements/field_ref.html">
|
||||
<link rel="import" href="src/observatory_elements/field_view.html">
|
||||
<link rel="import" href="src/observatory_elements/function_ref.html">
|
||||
<link rel="import" href="src/observatory_elements/function_view.html">
|
||||
<link rel="import" href="src/observatory_elements/isolate_list.html">
|
||||
<link rel="import" href="src/observatory_elements/isolate_summary.html">
|
||||
<link rel="import" href="src/observatory_elements/instance_ref.html">
|
||||
<link rel="import" href="src/observatory_elements/instance_view.html">
|
||||
<link rel="import" href="src/observatory_elements/json_view.html">
|
||||
<link rel="import" href="src/observatory_elements/library_ref.html">
|
||||
<link rel="import" href="src/observatory_elements/library_view.html">
|
||||
<link rel="import" href="src/observatory_elements/message_viewer.html">
|
||||
<link rel="import" href="src/observatory_elements/navigation_bar.html">
|
||||
@@ -22,6 +27,8 @@
|
||||
<link rel="import"
|
||||
href="src/observatory_elements/observatory_element.html">
|
||||
<link rel="import" href="src/observatory_elements/response_viewer.html">
|
||||
<link rel="import" href="src/observatory_elements/service_ref.html">
|
||||
<link rel="import" href="src/observatory_elements/script_ref.html">
|
||||
<link rel="import" href="src/observatory_elements/script_view.html">
|
||||
<link rel="import" href="src/observatory_elements/source_view.html">
|
||||
<link rel="import" href="src/observatory_elements/stack_trace.html">
|
||||
|
||||
@@ -6,7 +6,7 @@ part of observatory;
|
||||
|
||||
/// State for a running isolate.
|
||||
class Isolate extends Observable {
|
||||
@observable int id;
|
||||
@observable String id;
|
||||
@observable String name;
|
||||
@observable final Map<String, ScriptSource> scripts =
|
||||
toObservable(new Map<String, ScriptSource>());
|
||||
|
||||
@@ -9,8 +9,8 @@ class IsolateManager extends Observable {
|
||||
ObservatoryApplication _application;
|
||||
ObservatoryApplication get application => _application;
|
||||
|
||||
@observable final Map<int, Isolate> isolates =
|
||||
toObservable(new Map<int, Isolate>());
|
||||
@observable final Map<String, Isolate> isolates =
|
||||
toObservable(new Map<String, Isolate>());
|
||||
|
||||
static bool _foundIsolateInMembers(int id, List<Map> members) {
|
||||
return members.any((E) => E['id'] == id);
|
||||
@@ -24,7 +24,7 @@ class IsolateManager extends Observable {
|
||||
});
|
||||
}
|
||||
|
||||
Isolate getIsolate(int id) {
|
||||
Isolate getIsolate(String id) {
|
||||
Isolate isolate = isolates[id];
|
||||
if (isolate == null) {
|
||||
isolate = new Isolate(id, '');
|
||||
|
||||
@@ -10,7 +10,7 @@ part of observatory;
|
||||
class LocationManager extends Observable {
|
||||
static const int InvalidIsolateId = 0;
|
||||
static const String defaultHash = '#/isolates/';
|
||||
static final RegExp currentIsolateMatcher = new RegExp(r"#/isolates/\d+/");
|
||||
static final RegExp currentIsolateMatcher = new RegExp(r"#/isolates/\d+");
|
||||
|
||||
ObservatoryApplication _application;
|
||||
ObservatoryApplication get application => _application;
|
||||
@@ -48,24 +48,15 @@ class LocationManager extends Observable {
|
||||
return currentIsolateAnchorPrefix() != null;
|
||||
}
|
||||
|
||||
bool get isScriptLink {
|
||||
String type = currentHashUri.queryParameters['type'];
|
||||
return type == 'Script';
|
||||
}
|
||||
|
||||
String get scriptName {
|
||||
return Uri.decodeQueryComponent(currentHashUri.queryParameters['name']);
|
||||
}
|
||||
|
||||
/// Extract the current isolate id as an integer. Returns [InvalidIsolateId]
|
||||
/// if none is present in window.location.
|
||||
int currentIsolateId() {
|
||||
String isolatePrefix = currentIsolateAnchorPrefix();
|
||||
if (isolatePrefix == null) {
|
||||
return InvalidIsolateId;
|
||||
String currentIsolateId() {
|
||||
var prefix = currentIsolateAnchorPrefix();
|
||||
if (prefix == null) {
|
||||
return '';
|
||||
}
|
||||
String id = isolatePrefix.split("/")[2];
|
||||
return int.parse(id);
|
||||
// Chop off the '/#'.
|
||||
return prefix.substring(2);
|
||||
}
|
||||
|
||||
/// If no anchor is set, set the default anchor and return true.
|
||||
@@ -99,59 +90,16 @@ class LocationManager extends Observable {
|
||||
return relativeLink(isolateId, l);
|
||||
}
|
||||
|
||||
/// Create a request for [objectId] on the current isolate.
|
||||
/// Create a request for [scriptURL] on the current isolate.
|
||||
@observable
|
||||
String currentIsolateObjectLink(int objectId) {
|
||||
var isolateId = currentIsolateId();
|
||||
if (isolateId == LocationManager.InvalidIsolateId) {
|
||||
return defaultHash;
|
||||
}
|
||||
return objectLink(isolateId, objectId);
|
||||
}
|
||||
|
||||
/// Create a request for [cid] on the current isolate.
|
||||
@observable
|
||||
String currentIsolateClassLink(int cid) {
|
||||
var isolateId = currentIsolateId();
|
||||
if (isolateId == LocationManager.InvalidIsolateId) {
|
||||
return defaultHash;
|
||||
}
|
||||
return classLink(isolateId, cid);
|
||||
}
|
||||
|
||||
/// Create a request for the script [objectId] with script [name].
|
||||
@observable
|
||||
String currentIsolateScriptLink(int objectId, String name) {
|
||||
var isolateId = currentIsolateId();
|
||||
if (isolateId == LocationManager.InvalidIsolateId) {
|
||||
return defaultHash;
|
||||
}
|
||||
return scriptLink(isolateId, objectId, name);
|
||||
String currentIsolateScriptLink(String scriptURL) {
|
||||
var encoded = Uri.encodeComponent(scriptURL);
|
||||
return currentIsolateRelativeLink('scripts/$encoded');
|
||||
}
|
||||
|
||||
/// Create a request for [l] on [isolateId].
|
||||
@observable
|
||||
String relativeLink(int isolateId, String l) {
|
||||
return '#/isolates/$isolateId/$l';
|
||||
}
|
||||
|
||||
/// Create a request for [objectId] on [isolateId].
|
||||
@observable
|
||||
String objectLink(int isolateId, int objectId) {
|
||||
return '#/isolates/$isolateId/objects/$objectId';
|
||||
}
|
||||
|
||||
/// Create a request for [cid] on [isolateId].
|
||||
@observable
|
||||
String classLink(int isolateId, int cid) {
|
||||
return '#/isolates/$isolateId/classes/$cid';
|
||||
}
|
||||
|
||||
@observable
|
||||
/// Create a request for the script [objectId] with script [url].
|
||||
String scriptLink(int isolateId, int objectId, String name) {
|
||||
String encodedName = Uri.encodeQueryComponent(name);
|
||||
return '#/isolates/$isolateId/objects/$objectId'
|
||||
'?type=Script&name=$encodedName';
|
||||
String relativeLink(String isolateId, String l) {
|
||||
return '#/$isolateId/$l';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,12 @@ abstract class RequestManager extends Observable {
|
||||
|
||||
/// Parse
|
||||
void parseResponses(String responseString) {
|
||||
var r = JSON.decode(responseString);
|
||||
var r;
|
||||
try {
|
||||
r = JSON.decode(responseString);
|
||||
} catch (e) {
|
||||
setResponseError(e.message);
|
||||
}
|
||||
if (r is Map) {
|
||||
setResponses([r]);
|
||||
} else {
|
||||
@@ -34,7 +39,7 @@ abstract class RequestManager extends Observable {
|
||||
}
|
||||
}
|
||||
|
||||
void setResponseError(HttpRequest request) {
|
||||
void setResponseRequestError(HttpRequest request) {
|
||||
String error = '${request.status} ${request.statusText}';
|
||||
if (request.status == 0) {
|
||||
error = 'No service found. Did you run with --enable-vm-service ?';
|
||||
@@ -45,52 +50,20 @@ abstract class RequestManager extends Observable {
|
||||
}]);
|
||||
}
|
||||
|
||||
void setResponseError(String message) {
|
||||
setResponses([{
|
||||
'type': 'Error',
|
||||
'text': message
|
||||
}]);
|
||||
}
|
||||
|
||||
/// Request [requestString] from the VM service. Updates [responses].
|
||||
/// Will trigger [interceptor] if one is set.
|
||||
void get(String requestString) {
|
||||
if (_application.locationManager.isScriptLink) {
|
||||
// We cache script sources.
|
||||
String scriptName = _application.locationManager.scriptName;
|
||||
getScriptSource(scriptName, requestString).then((source) {
|
||||
if (source != null) {
|
||||
setResponses([{
|
||||
'type': 'Script',
|
||||
'source': source
|
||||
}]);
|
||||
} else {
|
||||
setResponses([{
|
||||
'type': 'RequestError',
|
||||
'error': 'Source for $scriptName could not be loaded.'
|
||||
}]);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
request(requestString).then((responseString) {
|
||||
parseResponses(responseString);
|
||||
}).catchError((e) {
|
||||
if (e is FormatException) {
|
||||
setResponseError(e.message);
|
||||
} else {
|
||||
setResponseError(e.target);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Future<ScriptSource> getScriptSource(String name, String requestString) {
|
||||
int isolateId = _application.locationManager.currentIsolateId();
|
||||
Isolate isolate = _application.isolateManager.getIsolate(isolateId);
|
||||
ScriptSource source = isolate.scripts[name];
|
||||
if (source != null) {
|
||||
return new Future.value(source);
|
||||
}
|
||||
return request(requestString).then((responseString) {
|
||||
var r = JSON.decode(responseString);
|
||||
ScriptSource scriptSource = new ScriptSource(r);
|
||||
isolate.scripts[name] = scriptSource;
|
||||
return scriptSource;
|
||||
request(requestString).then((responseString) {
|
||||
parseResponses(responseString);
|
||||
}).catchError((e) {
|
||||
setResponseError(e.target);
|
||||
setResponseRequestError(e.target);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// Copyright (c) 2013, 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 class_ref_element;
|
||||
|
||||
import 'package:polymer/polymer.dart';
|
||||
import 'service_ref.dart';
|
||||
|
||||
@CustomTag('class-ref')
|
||||
class ClassRefElement extends ServiceRefElement {
|
||||
ClassRefElement.created() : super.created();
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<head>
|
||||
<link rel="import" href="service_ref.html">
|
||||
</head>
|
||||
<polymer-element name="class-ref" extends="service-ref">
|
||||
<template>
|
||||
<a href="{{ url }}">{{ name }}</a>
|
||||
</template>
|
||||
<script type="application/dart" src="class_ref.dart"></script>
|
||||
</polymer-element>
|
||||
@@ -2,7 +2,9 @@
|
||||
<link rel="import" href="observatory_element.html">
|
||||
<link rel="import" href="error_view.html">
|
||||
<link rel="import" href="field_ref.html">
|
||||
<link rel="import" href="function_ref.html">
|
||||
<link rel="import" href="instance_ref.html">
|
||||
<link rel="import" href="library_ref.html">
|
||||
</head>
|
||||
<polymer-element name="class-view" extends="observatory-element">
|
||||
<template>
|
||||
@@ -13,13 +15,9 @@
|
||||
class <strong>{{ cls['user_name'] }}</strong>
|
||||
<template if="{{ cls['super']['type'] != 'Null' }}">
|
||||
extends
|
||||
<a href="{{ app.locationManager.currentIsolateClassLink(cls['super']['id'])}}">
|
||||
{{ cls['super']['user_name'] }}
|
||||
</a>
|
||||
<class-ref app="{{ app }}" ref="{{ cls['super'] }}"></class-ref>
|
||||
</template>
|
||||
<a class="pull-right" href="{{ app.locationManager.currentIsolateObjectLink(cls['library']['id'])}}">
|
||||
{{ cls['library']['name'] }}
|
||||
</a>
|
||||
<library-ref app="{{ app }}" ref="{{ cls['library'] }}"></library-ref>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<table class="table table-hover">
|
||||
@@ -49,8 +47,8 @@
|
||||
<table class="table table-hover">
|
||||
<tbody>
|
||||
<tr template repeat="{{ field in cls['fields'] }}">
|
||||
<td><field-ref app="{{ app }}" field="{{ field }}"></field-ref></td>
|
||||
<td><instance-ref app="{{ app }}" instance="{{ field['value'] }}"></instance-ref></td>
|
||||
<td><field-ref app="{{ app }}" ref="{{ field }}"></field-ref></td>
|
||||
<td><instance-ref app="{{ app }}" ref="{{ field['value'] }}"></instance-ref></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -64,8 +62,8 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr template repeat="{{ function in cls['functions'] }}">
|
||||
<td><a href="{{ app.locationManager.currentIsolateObjectLink(function['id'])}}">{{ function['user_name'] }}</a></td>
|
||||
<td><a href="{{ app.locationManager.currentIsolateObjectLink(function['id'])}}">{{ function['name'] }}</a></td>
|
||||
<td><function-ref app="{{ app }}" ref="{{ function }}"></function-ref></td>
|
||||
<td><function-ref app="{{ app }}" ref="{{ function }}" internal></function-ref></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// Copyright (c) 2013, 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 code_ref_element;
|
||||
|
||||
import 'package:polymer/polymer.dart';
|
||||
import 'service_ref.dart';
|
||||
|
||||
@CustomTag('code-ref')
|
||||
class CodeRefElement extends ServiceRefElement {
|
||||
CodeRefElement.created() : super.created();
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<head>
|
||||
<link rel="import" href="service_ref.html">
|
||||
</head>
|
||||
<polymer-element name="code-ref" extends="service-ref">
|
||||
<template>
|
||||
<a href="{{ url }}">{{ name }}</a>
|
||||
</template>
|
||||
<script type="application/dart" src="code_ref.dart"></script>
|
||||
</polymer-element>
|
||||
@@ -1,5 +1,6 @@
|
||||
<head>
|
||||
<link rel="import" href="disassembly_entry.html">
|
||||
<link rel="import" href="function_ref.html">
|
||||
<link rel="import" href="observatory_element.html">
|
||||
</head>
|
||||
<polymer-element name="code-view" extends="observatory-element">
|
||||
@@ -8,9 +9,7 @@
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<div class="{{ cssPanelClass }}">
|
||||
<div class="panel-heading">
|
||||
<a href="{{ app.locationManager.currentIsolateObjectLink(code['function']['id'])}}">
|
||||
{{ code['function']['user_name'] }} ({{ code['function']['name'] }})
|
||||
</a>
|
||||
<function-ref app="{{ app }}" ref="{{ code['function'] }}"></function-ref>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
|
||||
@@ -5,10 +5,9 @@
|
||||
library field_ref_element;
|
||||
|
||||
import 'package:polymer/polymer.dart';
|
||||
import 'observatory_element.dart';
|
||||
import 'service_ref.dart';
|
||||
|
||||
@CustomTag('field-ref')
|
||||
class FieldRefElement extends ObservatoryElement {
|
||||
@published Map field;
|
||||
class FieldRefElement extends ServiceRefElement {
|
||||
FieldRefElement.created() : super.created();
|
||||
}
|
||||
@@ -1,19 +1,19 @@
|
||||
<head>
|
||||
<link rel="import" href="class_ref.html">
|
||||
<link rel="import" href="observatory_element.html">
|
||||
<link rel="import" href="service_ref.html">
|
||||
</head>
|
||||
<polymer-element name="field-ref" extends="observatory-element">
|
||||
<polymer-element name="field-ref" extends="service-ref">
|
||||
<template>
|
||||
<div>
|
||||
<template if="{{ field['final'] }}"> final </template>
|
||||
<template if="{{ field['const'] }}"> const </template>
|
||||
<template if="{{ (field['declared_type']['name'] == 'dynamic' && !field['final'] && !field['const']) }}">
|
||||
<template if="{{ ref['final'] }}"> final </template>
|
||||
<template if="{{ ref['const'] }}"> const </template>
|
||||
<template if="{{ (ref['declared_type']['name'] == 'dynamic' && !ref['final'] && !ref['const']) }}">
|
||||
var
|
||||
</template>
|
||||
<template if="{{ (field['declared_type']['name'] != 'dynamic') }}">
|
||||
<a href="{{ app.locationManager.currentIsolateClassLink(field['declared_type']['id']) }}">
|
||||
{{ field['declared_type']['user_name'] }} </a>
|
||||
<template if="{{ (ref['declared_type']['name'] != 'dynamic') }}">
|
||||
<class-ref app="{{ app }}" ref="{{ ref['declared_type'] }}"></class-ref>
|
||||
</template>
|
||||
<a href="{{ app.locationManager.currentIsolateObjectLink(field['id'])}}">
|
||||
{{ field['user_name'] }} </a>
|
||||
<a href="{{ url }}">{{ name }}</a>
|
||||
</div>
|
||||
</template> <script type="application/dart" src="field_ref.dart"></script> </polymer-element>
|
||||
@@ -1,4 +1,5 @@
|
||||
<head>
|
||||
<link rel="import" href="class_ref.html">
|
||||
<link rel="import" href="observatory_element.html">
|
||||
</head>
|
||||
<polymer-element name="field-view" extends="observatory-element">
|
||||
@@ -10,10 +11,8 @@
|
||||
<template if="{{ field['static'] }}">static</template>
|
||||
<template if="{{ field['final'] }}">final</template>
|
||||
<template if="{{ field['const'] }}">const</template>
|
||||
{{ field['user_name'] }} ({{ field['name'] }})
|
||||
<a class="pull-right" href="{{ app.locationManager.currentIsolateClassLink(field['class']['id'])}}">
|
||||
{{ field['class']['user_name'] }}
|
||||
</a>
|
||||
{{ field['user_name'] }} ({{ field['name'] }})
|
||||
<class-ref app="{{ app }}" ref="{{ field['class'] }}"></class-ref>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<template if="{{ field['guard_class'] == 'dynamic'}}">
|
||||
@@ -22,9 +21,9 @@
|
||||
assigned a single type, performance may improve.
|
||||
</div>
|
||||
</template>
|
||||
<template if="{{ field['guard_class'] != 'dynamic'}}">
|
||||
<template if="{{ (field['guard_class'] != 'dynamic') && (field['guard_class'] != 'unknown') }}">
|
||||
<div class="alert alert-success">Field has monomorphic type</div>
|
||||
<template if="{{ (field['guard_class'] != 'dynamic') &&
|
||||
<template if="{{ (field['guard_class'] != 'dynamic') &&
|
||||
field['guard_nullable'] }}">
|
||||
<div class="alert alert-info">
|
||||
Field has been assigned null. If a field is never assigned null,
|
||||
@@ -32,9 +31,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<blockquote>
|
||||
<a href="{{ app.locationManager.currentIsolateClassLink(field['guard_class']['id'])}}">
|
||||
{{ field['guard_class']['user_name'] }}
|
||||
</a>
|
||||
<class-ref app="{{ app }}" ref="{{ field['guard_class'] }}"></class-ref>
|
||||
</blockquote>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// Copyright (c) 2013, 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 function_ref_element;
|
||||
|
||||
import 'package:polymer/polymer.dart';
|
||||
import 'service_ref.dart';
|
||||
|
||||
@CustomTag('function-ref')
|
||||
class FunctionRefElement extends ServiceRefElement {
|
||||
FunctionRefElement.created() : super.created();
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<head>
|
||||
<link rel="import" href="service_ref.html">
|
||||
</head>
|
||||
<polymer-element name="function-ref" extends="service-ref">
|
||||
<template>
|
||||
<a href="{{ url }}">{{ name }}</a>
|
||||
</template>
|
||||
<script type="application/dart" src="function_ref.dart"></script>
|
||||
</polymer-element>
|
||||
@@ -1,4 +1,6 @@
|
||||
<head>
|
||||
<link rel="import" href="class_ref.html">
|
||||
<link rel="import" href="code_ref.html">
|
||||
<link rel="import" href="observatory_element.html">
|
||||
</head>
|
||||
<polymer-element name="function-view" extends="observatory-element">
|
||||
@@ -7,15 +9,13 @@
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<div class="panel panel-warning">
|
||||
<div class="panel-heading">
|
||||
{{ function['user_name'] }} ({{ function['name'] }})
|
||||
<a class="pull-right" href="{{ app.locationManager.currentIsolateClassLink(function['class']['id'])}}">
|
||||
{{ function['class']['name'] }}
|
||||
</a>
|
||||
{{ function['user_name'] }} ({{ function['name'] }})
|
||||
<class-ref app="{{ app }}" ref="{{ function['class'] }}"></class-ref>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div>
|
||||
<a class="btn btn-primary" href="{{ app.locationManager.currentIsolateObjectLink(function['code']['id'])}}">Current Code</a>
|
||||
<a class="btn btn-info" href="{{ app.locationManager.currentIsolateObjectLink(function['unoptimized_code']['id'])}}">Unoptimized Code</a>
|
||||
<code-ref app="{{ app }}" ref="{{ function['code'] }}"></code-ref>
|
||||
<code-ref app="{{ app }}" ref="{{ function['unoptimized_code'] }}"></code-ref>
|
||||
</div>
|
||||
<table class="table table-hover">
|
||||
<tbody>
|
||||
|
||||
@@ -5,10 +5,16 @@
|
||||
library instance_ref_element;
|
||||
|
||||
import 'package:polymer/polymer.dart';
|
||||
import 'observatory_element.dart';
|
||||
import 'service_ref.dart';
|
||||
|
||||
@CustomTag('instance-ref')
|
||||
class InstanceRefElement extends ObservatoryElement {
|
||||
@published Map instance;
|
||||
class InstanceRefElement extends ServiceRefElement {
|
||||
InstanceRefElement.created() : super.created();
|
||||
|
||||
String get name {
|
||||
if (ref == null) {
|
||||
return super.name;
|
||||
}
|
||||
return ref['preview'];
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,17 @@
|
||||
<head>
|
||||
<link rel="import" href="observatory_element.html">
|
||||
<link rel="import" href="service_ref.html">
|
||||
</head>
|
||||
<polymer-element name="instance-ref" extends="observatory-element">
|
||||
<polymer-element name="instance-ref" extends="service-ref">
|
||||
<template>
|
||||
<div>
|
||||
<template if="{{ (instance['type'] == 'null') }}">
|
||||
<template if="{{ (ref['type'] == 'null') }}">
|
||||
{{ "null" }}
|
||||
</template>
|
||||
<template if="{{ (instance['type'] != 'null') }}">
|
||||
<a href="{{ app.locationManager.currentIsolateObjectLink(instance['id'])}}">
|
||||
{{ instance['preview'] }}
|
||||
</a>
|
||||
<template if="{{ (ref['type'] != 'null') }}">
|
||||
<a href="{{ url }}">{{ name }} </a>
|
||||
</template>
|
||||
</div>
|
||||
</template> <script type="application/dart" src="instance_ref.dart"></script> </polymer-element>
|
||||
</template>
|
||||
<script type="application/dart" src="instance_ref.dart"></script>
|
||||
</polymer-element>
|
||||
@@ -1,4 +1,5 @@
|
||||
<head>
|
||||
<link rel="import" href="class_ref.html">
|
||||
<link rel="import" href="observatory_element.html">
|
||||
<link rel="import" href="error_view.html">
|
||||
<link rel="import" href="field_ref.html">
|
||||
@@ -8,12 +9,10 @@
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<div class="panel panel-warning">
|
||||
<div class="panel panel-warning">
|
||||
<div class="panel-heading">
|
||||
Instance of
|
||||
<a href="{{ app.locationManager.currentIsolateClassLink(instance['class']['id'])}}">
|
||||
{{ instance['class']['user_name'] }}
|
||||
</a>
|
||||
<class-ref app="{{ app }}" ref="{{ instance['class'] }}"></class-ref>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<template if="{{ instance['error'] == null }}">
|
||||
@@ -28,8 +27,8 @@
|
||||
<table class="table table-hover">
|
||||
<tbody>
|
||||
<tr template repeat="{{ field in instance['fields'] }}">
|
||||
<td><field-ref app="{{ app }}" field="{{ field }}"></field-ref></td>
|
||||
<td><instance-ref app="{{ app }}" instance="{{ field['value'] }}"></instance-ref></td>
|
||||
<td><field-ref app="{{ app }}" ref="{{ field }}"></field-ref></td>
|
||||
<td><instance-ref app="{{ app }}" ref="{{ field['value'] }}"></instance-ref></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -44,4 +43,3 @@
|
||||
</template>
|
||||
<script type="application/dart" src="instance_view.dart"></script>
|
||||
</polymer-element>
|
||||
t>
|
||||
@@ -9,7 +9,7 @@ import 'observatory_element.dart';
|
||||
|
||||
@CustomTag('isolate-summary')
|
||||
class IsolateSummaryElement extends ObservatoryElement {
|
||||
@published int isolate;
|
||||
@published String isolate;
|
||||
@published String name = '';
|
||||
|
||||
IsolateSummaryElement.created() : super.created();
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// Copyright (c) 2013, 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 library_ref_element;
|
||||
|
||||
import 'package:polymer/polymer.dart';
|
||||
import 'service_ref.dart';
|
||||
|
||||
@CustomTag('library-ref')
|
||||
class LibraryRefElement extends ServiceRefElement {
|
||||
LibraryRefElement.created() : super.created();
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<head>
|
||||
<link rel="import" href="service_ref.html">
|
||||
</head>
|
||||
<polymer-element name="library-ref" extends="service-ref">
|
||||
<template>
|
||||
<a href="{{ url }}">{{ name }}</a>
|
||||
</template>
|
||||
<script type="application/dart" src="library_ref.dart"></script>
|
||||
</polymer-element>
|
||||
@@ -1,7 +1,11 @@
|
||||
<head>
|
||||
<link rel="import" href="observatory_element.html">
|
||||
<link rel="import" href="class_ref.html">
|
||||
<link rel="import" href="field_ref.html">
|
||||
<link rel="import" href="function_ref.html">
|
||||
<link rel="import" href="instance_ref.html">
|
||||
<link rel="import" href="library_ref.html">
|
||||
<link rel="import" href="observatory_element.html">
|
||||
<link rel="import" href="script_ref.html">
|
||||
</head>
|
||||
<polymer-element name="library-view" extends="observatory-element">
|
||||
<template>
|
||||
@@ -14,7 +18,7 @@
|
||||
{{ script['kind'] }}
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{ app.locationManager.currentIsolateScriptLink(script['id'], script['name']) }}">{{ script['name'] }}</a>
|
||||
<script-ref app="{{ app }}" ref="{{ script }}"></script-ref>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -24,9 +28,7 @@
|
||||
<tbody>
|
||||
<tr template repeat="{{ lib in library['libraries'] }}">
|
||||
<td>
|
||||
<a href="{{ app.locationManager.currentIsolateObjectLink(lib['id'])}}">
|
||||
{{ lib['url'] }}
|
||||
</a>
|
||||
<library-ref app="{{ app }}" ref="{{ lib }}"></library-ref>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -35,8 +37,8 @@
|
||||
<table class="table table-hover">
|
||||
<tbody>
|
||||
<tr template repeat="{{ variable in library['variables'] }}">
|
||||
<td><field-ref app="{{ app }}" field="{{ variable }}"></field-ref></td>
|
||||
<td><instance-ref app="{{ app }}" instance="{{ variable['value'] }}"></instance-ref></td>
|
||||
<td><field-ref app="{{ app }}" ref="{{ variable }}"></field-ref></td>
|
||||
<td><instance-ref app="{{ app }}" ref="{{ variable['value'] }}"></instance-ref></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -45,9 +47,7 @@
|
||||
<tbody>
|
||||
<tr template repeat="{{ func in library['functions'] }}">
|
||||
<td>
|
||||
<a href="{{ app.locationManager.currentIsolateObjectLink(func['id'])}}">
|
||||
{{ func['user_name'] }}
|
||||
</a>
|
||||
<function-ref app="{{ app }}" ref="{{ func }}"></function-ref>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -63,14 +63,10 @@
|
||||
<tbody>
|
||||
<tr template repeat="{{ cls in library['classes'] }}">
|
||||
<td>
|
||||
<a href="{{ app.locationManager.currentIsolateClassLink(cls['id']) }}">
|
||||
{{ cls['user_name'] }}
|
||||
</a>
|
||||
<class-ref app="{{ app }}" ref="{{ cls }}"></class-ref>
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{ app.locationManager.currentIsolateClassLink(cls['id']) }}">
|
||||
{{ cls['name'] }}
|
||||
</a>
|
||||
<class-ref app="{{ app }}" ref="{{ cls }}" internal></class-ref>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
@@ -8,10 +8,6 @@
|
||||
<a class="navbar-brand" href="">Observatory</a>
|
||||
</div>
|
||||
<div class="collapse navbar-collapse navbar-ex1-collapse">
|
||||
<input class="span2 pull-right navbar-form"
|
||||
placeholder="VM Address"
|
||||
type="text"
|
||||
value="{{ app.requestManager.prefix }}">
|
||||
</div>
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
@@ -22,6 +22,10 @@ class ObservatoryElement extends PolymerElement {
|
||||
super.leftView();
|
||||
}
|
||||
|
||||
void attributeChanged(String name, String oldValue, String newValue) {
|
||||
super.attributeChanged(name, oldValue, newValue);
|
||||
}
|
||||
|
||||
@published ObservatoryApplication app;
|
||||
bool get applyAuthorStyles => true;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// Copyright (c) 2013, 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 script_ref_element;
|
||||
|
||||
import 'package:polymer/polymer.dart';
|
||||
import 'service_ref.dart';
|
||||
|
||||
@CustomTag('script-ref')
|
||||
class ScriptRefElement extends ServiceRefElement {
|
||||
ScriptRefElement.created() : super.created();
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<head>
|
||||
<link rel="import" href="observatory_element.html">
|
||||
<link rel="import" href="service_ref.html">
|
||||
</head>
|
||||
<polymer-element name="script-ref" extends="service-ref">
|
||||
<template>
|
||||
<a href="{{ url }}">{{ name }}</a>
|
||||
</template>
|
||||
<script type="application/dart" src="script_ref.dart"></script>
|
||||
</polymer-element>
|
||||
@@ -0,0 +1,38 @@
|
||||
// Copyright (c) 2013, 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 service_ref_element;
|
||||
|
||||
import 'package:polymer/polymer.dart';
|
||||
import 'observatory_element.dart';
|
||||
|
||||
@CustomTag('service-ref')
|
||||
class ServiceRefElement extends ObservatoryElement {
|
||||
@published Map ref;
|
||||
@published bool internal = false;
|
||||
ServiceRefElement.created() : super.created();
|
||||
|
||||
void refChanged(oldValue) {
|
||||
notifyPropertyChange(#url, "", url);
|
||||
notifyPropertyChange(#name, [], name);
|
||||
}
|
||||
|
||||
String get url {
|
||||
if ((app != null) && (ref != null)) {
|
||||
return app.locationManager.currentIsolateRelativeLink(ref['id']);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
String get name {
|
||||
if (ref == null) {
|
||||
return '';
|
||||
}
|
||||
String name_key = internal ? 'name' : 'user_name';
|
||||
if (ref[name_key] != null) {
|
||||
return ref[name_key];
|
||||
}
|
||||
return '';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<head>
|
||||
<link rel="import" href="observatory_element.html">
|
||||
</head>
|
||||
<polymer-element name="service-ref" extends="observatory-element">
|
||||
<script type="application/dart" src="service_ref.dart"></script>
|
||||
</polymer-element>
|
||||
@@ -1,5 +1,7 @@
|
||||
<head>
|
||||
<link rel="import" href="function_ref.html">
|
||||
<link rel="import" href="observatory_element.html">
|
||||
<link rel="import" href="script_ref.html">
|
||||
</head>
|
||||
<polymer-element name="stack-trace" extends="observatory-element">
|
||||
<template>
|
||||
@@ -9,15 +11,15 @@
|
||||
<tr>
|
||||
<th>Depth</th>
|
||||
<th>Function</th>
|
||||
<th>Url</th>
|
||||
<th>Script</th>
|
||||
<th>Line</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr template repeat="{{ frame in trace['members'] }}">
|
||||
<td>{{$index}}</td>
|
||||
<td><a href="{{app.locationManager.currentIsolateObjectLink(frame['function']['id'])}}">{{ frame['name'] }}</a></td>
|
||||
<td>{{ frame['url'] }}</td>
|
||||
<td><function-ref app="{{ app }}" ref="{{ frame['function'] }}"></function-ref></td>
|
||||
<td><script-ref app="{{ app }}" ref="{{ frame['script'] }}"></script-ref></td>
|
||||
<td>{{ frame['line'] }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
@@ -29,8 +29,9 @@ class RunningIsolates implements MessageRouter {
|
||||
var result = {};
|
||||
isolates.forEach((portId, runningIsolate) {
|
||||
members.add({
|
||||
'id': portId,
|
||||
'name': runningIsolate.name
|
||||
'type': 'Isolate',
|
||||
'id': 'isolates/$portId',
|
||||
'name': runningIsolate.name,
|
||||
});
|
||||
});
|
||||
result['type'] = 'IsolateList';
|
||||
|
||||
+250
-21
@@ -1808,6 +1808,32 @@ void Class::AddFunction(const Function& function) const {
|
||||
}
|
||||
|
||||
|
||||
intptr_t Class::FindFunctionIndex(const Function& needle) const {
|
||||
Isolate* isolate = Isolate::Current();
|
||||
if (EnsureIsFinalized(isolate) != Error::null()) {
|
||||
return -1;
|
||||
}
|
||||
ReusableHandleScope reused_handles(isolate);
|
||||
Array& funcs = reused_handles.ArrayHandle();
|
||||
funcs ^= functions();
|
||||
ASSERT(!funcs.IsNull());
|
||||
Function& function = reused_handles.FunctionHandle();
|
||||
String& function_name = reused_handles.StringHandle();
|
||||
String& needle_name = String::Handle(isolate);
|
||||
needle_name ^= needle.name();
|
||||
const intptr_t len = funcs.Length();
|
||||
for (intptr_t i = 0; i < len; i++) {
|
||||
function ^= funcs.At(i);
|
||||
function_name ^= function.name();
|
||||
if (function_name.Equals(needle_name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
// No function found.
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void Class::AddClosureFunction(const Function& function) const {
|
||||
GrowableObjectArray& closures =
|
||||
GrowableObjectArray::Handle(raw_ptr()->closure_functions_);
|
||||
@@ -1848,6 +1874,31 @@ RawFunction* Class::LookupClosureFunction(intptr_t token_pos) const {
|
||||
return closure.raw();
|
||||
}
|
||||
|
||||
intptr_t Class::FindClosureIndex(intptr_t token_pos) const {
|
||||
if (raw_ptr()->closure_functions_ == GrowableObjectArray::null()) {
|
||||
return -1;
|
||||
}
|
||||
Isolate* isolate = Isolate::Current();
|
||||
ReusableHandleScope reused_handles(isolate);
|
||||
const GrowableObjectArray& closures =
|
||||
GrowableObjectArray::Handle(isolate, raw_ptr()->closure_functions_);
|
||||
Function& closure = reused_handles.FunctionHandle();
|
||||
intptr_t num_closures = closures.Length();
|
||||
intptr_t best_fit_token_pos = -1;
|
||||
intptr_t best_fit_index = -1;
|
||||
for (intptr_t i = 0; i < num_closures; i++) {
|
||||
closure ^= closures.At(i);
|
||||
ASSERT(!closure.IsNull());
|
||||
if ((closure.token_pos() <= token_pos) &&
|
||||
(token_pos <= closure.end_token_pos()) &&
|
||||
(best_fit_token_pos < closure.token_pos())) {
|
||||
best_fit_index = i;
|
||||
best_fit_token_pos = closure.token_pos();
|
||||
}
|
||||
}
|
||||
return best_fit_index;
|
||||
}
|
||||
|
||||
|
||||
void Class::set_signature_function(const Function& value) const {
|
||||
ASSERT(value.IsClosureFunction() || value.IsSignatureFunction());
|
||||
@@ -2400,6 +2451,32 @@ void Class::SetFields(const Array& value) const {
|
||||
}
|
||||
|
||||
|
||||
intptr_t Class::FindFieldIndex(const Field& needle) const {
|
||||
Isolate* isolate = Isolate::Current();
|
||||
if (EnsureIsFinalized(isolate) != Error::null()) {
|
||||
return -1;
|
||||
}
|
||||
ReusableHandleScope reused_handles(isolate);
|
||||
Array& fields_array = reused_handles.ArrayHandle();
|
||||
fields_array ^= fields();
|
||||
ASSERT(!fields_array.IsNull());
|
||||
Field& field = reused_handles.FieldHandle();
|
||||
String& field_name = reused_handles.StringHandle();
|
||||
String& needle_name = String::Handle(isolate);
|
||||
needle_name ^= needle.name();
|
||||
const intptr_t len = fields_array.Length();
|
||||
for (intptr_t i = 0; i < len; i++) {
|
||||
field ^= fields_array.At(i);
|
||||
field_name ^= field.name();
|
||||
if (field_name.Equals(needle_name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
// No field found found.
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
template <class FakeInstance>
|
||||
RawClass* Class::New(intptr_t index) {
|
||||
ASSERT(Object::class_class() != Class::null());
|
||||
@@ -3249,7 +3326,7 @@ void Class::PrintToJSONStream(JSONStream* stream, bool ref) const {
|
||||
const char* user_visible_class_name =
|
||||
String::Handle(UserVisibleName()).ToCString();
|
||||
jsobj.AddProperty("type", JSONType(ref));
|
||||
jsobj.AddProperty("id", id());
|
||||
jsobj.AddPropertyF("id", "classes/%" Pd "", id());
|
||||
jsobj.AddProperty("name", internal_class_name);
|
||||
jsobj.AddProperty("user_name", user_visible_class_name);
|
||||
if (!ref) {
|
||||
@@ -5633,11 +5710,26 @@ void Function::PrintToJSONStream(JSONStream* stream, bool ref) const {
|
||||
const char* internal_function_name = String::Handle(name()).ToCString();
|
||||
const char* function_name =
|
||||
String::Handle(QualifiedUserVisibleName()).ToCString();
|
||||
ObjectIdRing* ring = Isolate::Current()->object_id_ring();
|
||||
intptr_t id = ring->GetIdForObject(raw());
|
||||
Class& cls = Class::Handle(Owner());
|
||||
Error& err = Error::Handle();
|
||||
err ^= cls.EnsureIsFinalized(Isolate::Current());
|
||||
ASSERT(err.IsNull());
|
||||
const Function& func = *this;
|
||||
intptr_t id;
|
||||
if (IsNonImplicitClosureFunction()) {
|
||||
id = cls.FindClosureIndex(token_pos());
|
||||
} else {
|
||||
id = cls.FindFunctionIndex(func);
|
||||
}
|
||||
ASSERT(id >= 0);
|
||||
intptr_t cid = cls.id();
|
||||
JSONObject jsobj(stream);
|
||||
jsobj.AddProperty("type", JSONType(ref));
|
||||
jsobj.AddProperty("id", id);
|
||||
if (IsNonImplicitClosureFunction()) {
|
||||
jsobj.AddPropertyF("id", "classes/%" Pd "/closures/%" Pd "", cid, id);
|
||||
} else {
|
||||
jsobj.AddPropertyF("id", "classes/%" Pd "/functions/%" Pd "", cid, id);
|
||||
}
|
||||
jsobj.AddProperty("name", internal_function_name);
|
||||
jsobj.AddProperty("user_name", function_name);
|
||||
if (ref) return;
|
||||
@@ -5966,10 +6058,12 @@ void Field::PrintToJSONStreamWithInstance(JSONStream* stream,
|
||||
JSONObject jsobj(stream);
|
||||
const char* internal_field_name = String::Handle(name()).ToCString();
|
||||
const char* field_name = String::Handle(UserVisibleName()).ToCString();
|
||||
ObjectIdRing* ring = Isolate::Current()->object_id_ring();
|
||||
intptr_t id = ring->GetIdForObject(raw());
|
||||
Class& cls = Class::Handle(owner());
|
||||
intptr_t id = cls.FindFieldIndex(*this);
|
||||
ASSERT(id >= 0);
|
||||
intptr_t cid = cls.id();
|
||||
jsobj.AddProperty("type", JSONType(ref));
|
||||
jsobj.AddProperty("id", id);
|
||||
jsobj.AddPropertyF("id", "classes/%" Pd "/fields/%" Pd "", cid, id);
|
||||
jsobj.AddProperty("name", internal_field_name);
|
||||
jsobj.AddProperty("user_name", field_name);
|
||||
if (is_static()) {
|
||||
@@ -5979,7 +6073,7 @@ void Field::PrintToJSONStreamWithInstance(JSONStream* stream,
|
||||
const Object& valueObj = Object::Handle(instance.GetField(*this));
|
||||
jsobj.AddProperty("value", valueObj);
|
||||
}
|
||||
Class& cls = Class::Handle(owner());
|
||||
|
||||
jsobj.AddProperty("owner", cls);
|
||||
AbstractType& declared_type = AbstractType::Handle(type());
|
||||
cls = declared_type.type_class();
|
||||
@@ -7133,12 +7227,14 @@ const char* Script::ToCString() const {
|
||||
|
||||
void Script::PrintToJSONStream(JSONStream* stream, bool ref) const {
|
||||
JSONObject jsobj(stream);
|
||||
ObjectIdRing* ring = Isolate::Current()->object_id_ring();
|
||||
intptr_t id = ring->GetIdForObject(raw());
|
||||
jsobj.AddProperty("type", JSONType(ref));
|
||||
jsobj.AddProperty("id", id);
|
||||
const String& name = String::Handle(url());
|
||||
ASSERT(!name.IsNull());
|
||||
const String& encoded_url = String::Handle(String::EncodeURI(name));
|
||||
ASSERT(!encoded_url.IsNull());
|
||||
jsobj.AddPropertyF("id", "scripts/%s", encoded_url.ToCString());
|
||||
jsobj.AddProperty("name", name.ToCString());
|
||||
jsobj.AddProperty("user_name", name.ToCString());
|
||||
jsobj.AddProperty("kind", GetKindAsCString());
|
||||
if (ref) {
|
||||
return;
|
||||
@@ -8207,13 +8303,13 @@ const char* Library::ToCString() const {
|
||||
void Library::PrintToJSONStream(JSONStream* stream, bool ref) const {
|
||||
const char* library_name = String::Handle(name()).ToCString();
|
||||
const char* library_url = String::Handle(url()).ToCString();
|
||||
ObjectIdRing* ring = Isolate::Current()->object_id_ring();
|
||||
intptr_t id = ring->GetIdForObject(raw());
|
||||
intptr_t id = index();
|
||||
ASSERT(id >= 0);
|
||||
JSONObject jsobj(stream);
|
||||
jsobj.AddProperty("type", JSONType(ref));
|
||||
jsobj.AddProperty("id", id);
|
||||
jsobj.AddPropertyF("id", "libraries/%" Pd "", id);
|
||||
jsobj.AddProperty("name", library_name);
|
||||
jsobj.AddProperty("url", library_url);
|
||||
jsobj.AddProperty("user_name", library_url);
|
||||
if (ref) return;
|
||||
{
|
||||
JSONArray jsarr(&jsobj, "classes");
|
||||
@@ -9780,16 +9876,27 @@ const char* Code::ToCString() const {
|
||||
|
||||
|
||||
void Code::PrintToJSONStream(JSONStream* stream, bool ref) const {
|
||||
ObjectIdRing* ring = Isolate::Current()->object_id_ring();
|
||||
Isolate* isolate = Isolate::Current();
|
||||
ObjectIdRing* ring = isolate->object_id_ring();
|
||||
intptr_t id = ring->GetIdForObject(raw());
|
||||
JSONObject jsobj(stream);
|
||||
jsobj.AddProperty("type", JSONType(ref));
|
||||
jsobj.AddPropertyF("id", "objects/%" Pd "", id);
|
||||
Function& func = Function::Handle();
|
||||
String& name = String::Handle();
|
||||
func ^= function();
|
||||
ASSERT(!func.IsNull());
|
||||
name ^= func.name();
|
||||
const char* internal_function_name = name.ToCString();
|
||||
jsobj.AddPropertyF("name", "%s%s", is_optimized() ? "*" : "",
|
||||
internal_function_name);
|
||||
name ^= func.QualifiedUserVisibleName();
|
||||
const char* function_name = name.ToCString();
|
||||
jsobj.AddPropertyF("user_name", "%s%s", is_optimized() ? "*" : "",
|
||||
function_name);
|
||||
if (ref) {
|
||||
jsobj.AddProperty("type", "@Code");
|
||||
jsobj.AddProperty("id", id);
|
||||
return;
|
||||
}
|
||||
jsobj.AddProperty("type", "Code");
|
||||
jsobj.AddProperty("id", id);
|
||||
jsobj.AddProperty("is_optimized", is_optimized());
|
||||
jsobj.AddProperty("is_alive", is_alive());
|
||||
jsobj.AddProperty("function", Object::Handle(function()));
|
||||
@@ -11491,7 +11598,7 @@ void Instance::PrintToJSONStream(JSONStream* stream, bool ref) const {
|
||||
|
||||
JSONObject jsobj(stream);
|
||||
jsobj.AddProperty("type", JSONType(ref));
|
||||
jsobj.AddProperty("id", id);
|
||||
jsobj.AddPropertyF("id", "objects/%" Pd "", id);
|
||||
|
||||
Class& cls = Class::Handle(this->clazz());
|
||||
jsobj.AddProperty("class", cls);
|
||||
@@ -14350,6 +14457,128 @@ RawString* String::EscapeSpecialCharacters(const String& str) {
|
||||
}
|
||||
|
||||
|
||||
static bool IsPercent(int32_t c) {
|
||||
return c == '%';
|
||||
}
|
||||
|
||||
|
||||
static bool IsURISafeCharacter(int32_t c) {
|
||||
if ((c >= '0') && (c <= '9')) {
|
||||
return true;
|
||||
}
|
||||
if ((c >= 'a') && (c <= 'z')) {
|
||||
return true;
|
||||
}
|
||||
if ((c >= 'A') && (c <= 'Z')) {
|
||||
return true;
|
||||
}
|
||||
return (c == '-') || (c == '_') || (c == '.') || (c == '~');
|
||||
}
|
||||
|
||||
|
||||
static int32_t GetHexCharacter(int32_t c) {
|
||||
ASSERT(c >= 0);
|
||||
ASSERT(c < 16);
|
||||
const char* hex = "0123456789ABCDEF";
|
||||
return hex[c];
|
||||
}
|
||||
|
||||
|
||||
static int32_t GetHexValue(int32_t c) {
|
||||
if (c >= '0' && c <= '9') {
|
||||
return c - '0';
|
||||
}
|
||||
if (c >= 'A' && c <= 'F') {
|
||||
return c - 'A' + 10;
|
||||
}
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int32_t MergeHexCharacters(int32_t c1, int32_t c2) {
|
||||
return GetHexValue(c1) << 4 | GetHexValue(c2);
|
||||
}
|
||||
|
||||
|
||||
RawString* String::EncodeURI(const String& str) {
|
||||
// URI encoding is only specified for one byte strings.
|
||||
ASSERT(str.IsOneByteString() || str.IsExternalOneByteString());
|
||||
intptr_t num_escapes = 0;
|
||||
intptr_t len = str.Length();
|
||||
{
|
||||
CodePointIterator cpi(str);
|
||||
while (cpi.Next()) {
|
||||
int32_t code_point = cpi.Current();
|
||||
if (!IsURISafeCharacter(code_point)) {
|
||||
num_escapes += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
const String& dststr = String::Handle(
|
||||
OneByteString::New(len + num_escapes, Heap::kNew));
|
||||
{
|
||||
intptr_t index = 0;
|
||||
CodePointIterator cpi(str);
|
||||
while (cpi.Next()) {
|
||||
int32_t code_point = cpi.Current();
|
||||
if (!IsURISafeCharacter(code_point)) {
|
||||
OneByteString::SetCharAt(dststr, index, '%');
|
||||
OneByteString::SetCharAt(dststr, index + 1,
|
||||
GetHexCharacter(code_point >> 4));
|
||||
OneByteString::SetCharAt(dststr, index + 2,
|
||||
GetHexCharacter(code_point & 0xF));
|
||||
index += 3;
|
||||
} else {
|
||||
OneByteString::SetCharAt(dststr, index, code_point);
|
||||
index += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return dststr.raw();
|
||||
}
|
||||
|
||||
|
||||
RawString* String::DecodeURI(const String& str) {
|
||||
// URI encoding is only specified for one byte strings.
|
||||
ASSERT(str.IsOneByteString() || str.IsExternalOneByteString());
|
||||
CodePointIterator cpi(str);
|
||||
intptr_t num_escapes = 0;
|
||||
intptr_t len = str.Length();
|
||||
{
|
||||
CodePointIterator cpi(str);
|
||||
while (cpi.Next()) {
|
||||
int32_t code_point = cpi.Current();
|
||||
if (IsPercent(code_point)) {
|
||||
num_escapes += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
ASSERT(len - num_escapes > 0);
|
||||
const String& dststr = String::Handle(
|
||||
OneByteString::New(len - num_escapes, Heap::kNew));
|
||||
{
|
||||
intptr_t index = 0;
|
||||
CodePointIterator cpi(str);
|
||||
while (cpi.Next()) {
|
||||
int32_t code_point = cpi.Current();
|
||||
if (IsPercent(code_point)) {
|
||||
ASSERT(cpi.Next());
|
||||
int32_t ch1 = cpi.Current();
|
||||
cpi.Next();
|
||||
int32_t ch2 = cpi.Current();
|
||||
int32_t merged = MergeHexCharacters(ch1, ch2);
|
||||
OneByteString::SetCharAt(dststr, index, merged);
|
||||
} else {
|
||||
OneByteString::SetCharAt(dststr, index, code_point);
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
return dststr.raw();
|
||||
}
|
||||
|
||||
|
||||
RawString* String::NewFormatted(const char* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
|
||||
+7
-2
@@ -878,6 +878,7 @@ class Class : public Object {
|
||||
|
||||
RawArray* fields() const { return raw_ptr()->fields_; }
|
||||
void SetFields(const Array& value) const;
|
||||
intptr_t FindFieldIndex(const Field& field) const;
|
||||
|
||||
// Returns an array of all fields of this class and its superclasses indexed
|
||||
// by offset in words.
|
||||
@@ -889,12 +890,14 @@ class Class : public Object {
|
||||
RawArray* functions() const { return raw_ptr()->functions_; }
|
||||
void SetFunctions(const Array& value) const;
|
||||
void AddFunction(const Function& function) const;
|
||||
intptr_t FindFunctionIndex(const Function& function) const;
|
||||
|
||||
RawGrowableObjectArray* closures() const {
|
||||
return raw_ptr()->closure_functions_;
|
||||
}
|
||||
void AddClosureFunction(const Function& function) const;
|
||||
RawFunction* LookupClosureFunction(intptr_t token_pos) const;
|
||||
intptr_t FindClosureIndex(intptr_t token_pos) const;
|
||||
|
||||
RawFunction* LookupDynamicFunction(const String& name) const;
|
||||
RawFunction* LookupDynamicFunctionAllowPrivate(const String& name) const;
|
||||
@@ -5072,7 +5075,8 @@ class String : public Instance {
|
||||
intptr_t len);
|
||||
|
||||
static RawString* EscapeSpecialCharacters(const String& str);
|
||||
|
||||
static RawString* EncodeURI(const String& str);
|
||||
static RawString* DecodeURI(const String& str);
|
||||
static RawString* Concat(const String& str1,
|
||||
const String& str2,
|
||||
Heap::Space space = Heap::kNew);
|
||||
@@ -5163,7 +5167,6 @@ class OneByteString : public AllStatic {
|
||||
*CharAddr(str, index) = code_point;
|
||||
}
|
||||
static RawOneByteString* EscapeSpecialCharacters(const String& str);
|
||||
|
||||
// We use the same maximum elements for all strings.
|
||||
static const intptr_t kBytesPerElement = 1;
|
||||
static const intptr_t kMaxElements = String::kMaxElements;
|
||||
@@ -5387,6 +5390,8 @@ class ExternalOneByteString : public AllStatic {
|
||||
}
|
||||
|
||||
static RawOneByteString* EscapeSpecialCharacters(const String& str);
|
||||
static RawOneByteString* EncodeURI(const String& str);
|
||||
static RawOneByteString* DecodeURI(const String& str);
|
||||
|
||||
static const ClassId kClassId = kExternalOneByteStringCid;
|
||||
|
||||
|
||||
@@ -332,6 +332,32 @@ TEST_CASE(StringCompareTo) {
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE(StringEncodeURI) {
|
||||
const char* kInput =
|
||||
"file:///usr/local/johnmccutchan/workspace/dart-repo/dart/test.dart";
|
||||
const char* kOutput =
|
||||
"file%3A%2F%2F%2Fusr%2Flocal%2Fjohnmccutchan%2Fworkspace%2F"
|
||||
"dart-repo%2Fdart%2Ftest.dart";
|
||||
const String& input = String::Handle(String::New(kInput));
|
||||
const String& output = String::Handle(String::New(kOutput));
|
||||
const String& encoded = String::Handle(String::EncodeURI(input));
|
||||
EXPECT(output.Equals(encoded));
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE(StringDecodeURI) {
|
||||
const char* kOutput =
|
||||
"file:///usr/local/johnmccutchan/workspace/dart-repo/dart/test.dart";
|
||||
const char* kInput =
|
||||
"file%3A%2F%2F%2Fusr%2Flocal%2Fjohnmccutchan%2Fworkspace%2F"
|
||||
"dart-repo%2Fdart%2Ftest.dart";
|
||||
const String& input = String::Handle(String::New(kInput));
|
||||
const String& output = String::Handle(String::New(kOutput));
|
||||
const String& decoded = String::Handle(String::DecodeURI(input));
|
||||
EXPECT(output.Equals(decoded));
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE(Mint) {
|
||||
// On 64-bit architectures a Smi is stored in a 64 bit word. A Midint cannot
|
||||
// be allocated if it does fit into a Smi.
|
||||
@@ -2749,6 +2775,8 @@ TEST_CASE(FieldTests) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Expose helper function from object.cc for testing.
|
||||
bool EqualsIgnoringPrivate(const String& name, const String& private_name);
|
||||
|
||||
@@ -3391,6 +3419,140 @@ static RawClass* GetClass(const Library& lib, const char* name) {
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE(FindFieldIndex) {
|
||||
const char* kScriptChars =
|
||||
"class A {\n"
|
||||
" var a;\n"
|
||||
" var b;\n"
|
||||
"}\n"
|
||||
"class B {\n"
|
||||
" var d;\n"
|
||||
"}\n"
|
||||
"test() {\n"
|
||||
" new A();\n"
|
||||
" new B();\n"
|
||||
"}";
|
||||
Dart_Handle h_lib = TestCase::LoadTestScript(kScriptChars, NULL);
|
||||
EXPECT_VALID(h_lib);
|
||||
Dart_Handle result = Dart_Invoke(h_lib, NewString("test"), 0, NULL);
|
||||
EXPECT_VALID(result);
|
||||
Library& lib = Library::Handle();
|
||||
lib ^= Api::UnwrapHandle(h_lib);
|
||||
EXPECT(!lib.IsNull());
|
||||
const Class& class_a = Class::Handle(GetClass(lib, "A"));
|
||||
const Array& class_a_fields = Array::Handle(class_a.fields());
|
||||
const Class& class_b = Class::Handle(GetClass(lib, "B"));
|
||||
const Field& field_a = Field::Handle(GetField(class_a, "a"));
|
||||
const Field& field_b = Field::Handle(GetField(class_a, "b"));
|
||||
const Field& field_d = Field::Handle(GetField(class_b, "d"));
|
||||
intptr_t field_a_index = class_a.FindFieldIndex(field_a);
|
||||
intptr_t field_b_index = class_a.FindFieldIndex(field_b);
|
||||
intptr_t field_d_index = class_a.FindFieldIndex(field_d);
|
||||
// Valid index.
|
||||
EXPECT_GE(field_a_index, 0);
|
||||
// Valid index.
|
||||
EXPECT_GE(field_b_index, 0);
|
||||
// Invalid index.
|
||||
EXPECT_EQ(field_d_index, -1);
|
||||
Field& field_a_from_index = Field::Handle();
|
||||
field_a_from_index ^= class_a_fields.At(field_a_index);
|
||||
ASSERT(!field_a_from_index.IsNull());
|
||||
// Same field.
|
||||
EXPECT_EQ(field_a.raw(), field_a_from_index.raw());
|
||||
Field& field_b_from_index = Field::Handle();
|
||||
field_b_from_index ^= class_a_fields.At(field_b_index);
|
||||
ASSERT(!field_b_from_index.IsNull());
|
||||
// Same field.
|
||||
EXPECT_EQ(field_b.raw(), field_b_from_index.raw());
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE(FindFunctionIndex) {
|
||||
const char* kScriptChars =
|
||||
"class A {\n"
|
||||
" void a() {}\n"
|
||||
" void b() {}\n"
|
||||
"}\n"
|
||||
"class B {\n"
|
||||
" dynamic d() {}\n"
|
||||
"}\n"
|
||||
"test() {\n"
|
||||
" new A();\n"
|
||||
" new B();\n"
|
||||
"}";
|
||||
Dart_Handle h_lib = TestCase::LoadTestScript(kScriptChars, NULL);
|
||||
EXPECT_VALID(h_lib);
|
||||
Dart_Handle result = Dart_Invoke(h_lib, NewString("test"), 0, NULL);
|
||||
EXPECT_VALID(result);
|
||||
Library& lib = Library::Handle();
|
||||
lib ^= Api::UnwrapHandle(h_lib);
|
||||
EXPECT(!lib.IsNull());
|
||||
const Class& class_a = Class::Handle(GetClass(lib, "A"));
|
||||
const Array& class_a_funcs = Array::Handle(class_a.functions());
|
||||
const Class& class_b = Class::Handle(GetClass(lib, "B"));
|
||||
const Function& func_a = Function::Handle(GetFunction(class_a, "a"));
|
||||
const Function& func_b = Function::Handle(GetFunction(class_a, "b"));
|
||||
const Function& func_d = Function::Handle(GetFunction(class_b, "d"));
|
||||
intptr_t func_a_index = class_a.FindFunctionIndex(func_a);
|
||||
intptr_t func_b_index = class_a.FindFunctionIndex(func_b);
|
||||
intptr_t func_d_index = class_a.FindFunctionIndex(func_d);
|
||||
// Valid index.
|
||||
EXPECT_GE(func_a_index, 0);
|
||||
// Valid index.
|
||||
EXPECT_GE(func_b_index, 0);
|
||||
// Invalid index.
|
||||
EXPECT_EQ(func_d_index, -1);
|
||||
Function& func_a_from_index = Function::Handle();
|
||||
func_a_from_index ^= class_a_funcs.At(func_a_index);
|
||||
ASSERT(!func_a_from_index.IsNull());
|
||||
// Same function.
|
||||
EXPECT_EQ(func_a.raw(), func_a_from_index.raw());
|
||||
Function& func_b_from_index = Function::Handle();
|
||||
func_b_from_index ^= class_a_funcs.At(func_b_index);
|
||||
ASSERT(!func_b_from_index.IsNull());
|
||||
// Same function.
|
||||
EXPECT_EQ(func_b.raw(), func_b_from_index.raw());
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE(FindClosureIndex) {
|
||||
// Allocate the class first.
|
||||
const String& class_name = String::Handle(Symbols::New("MyClass"));
|
||||
const Script& script = Script::Handle();
|
||||
const Class& cls = Class::Handle(CreateDummyClass(class_name, script));
|
||||
const Array& functions = Array::Handle(Array::New(1));
|
||||
|
||||
Function& parent = Function::Handle();
|
||||
const String& parent_name = String::Handle(Symbols::New("foo_papa"));
|
||||
parent = Function::New(parent_name, RawFunction::kRegularFunction,
|
||||
false, false, false, false, false, cls, 0);
|
||||
functions.SetAt(0, parent);
|
||||
cls.SetFunctions(functions);
|
||||
|
||||
Function& function = Function::Handle();
|
||||
const String& function_name = String::Handle(Symbols::New("foo"));
|
||||
function = Function::NewClosureFunction(function_name, parent, 0);
|
||||
// Add closure function to class.
|
||||
cls.AddClosureFunction(function);
|
||||
|
||||
// Token position 0 should return a valid index.
|
||||
intptr_t good_closure_index = cls.FindClosureIndex(0);
|
||||
EXPECT_GE(good_closure_index, 0);
|
||||
// Token position 1 should return an invalid index.
|
||||
intptr_t bad_closure_index = cls.FindClosureIndex(1);
|
||||
EXPECT_EQ(bad_closure_index, -1);
|
||||
|
||||
// Retrieve closure function via index.
|
||||
const GrowableObjectArray& closures = GrowableObjectArray::Handle(
|
||||
cls.closures());
|
||||
Function& func_from_index = Function::Handle();
|
||||
func_from_index ^= closures.At(good_closure_index);
|
||||
|
||||
// Same closure function.
|
||||
EXPECT_EQ(func_from_index.raw(), function.raw());
|
||||
}
|
||||
|
||||
|
||||
static void PrintMetadata(const char* name, const Object& data) {
|
||||
if (data.IsError()) {
|
||||
OS::Print("Error in metadata evaluation for %s: '%s'\n",
|
||||
|
||||
+215
-11
@@ -196,15 +196,15 @@ static void HandleStackTrace(Isolate* isolate, JSONStream* js) {
|
||||
jsobj.AddProperty("type", "StackTrace");
|
||||
JSONArray jsarr(&jsobj, "members");
|
||||
intptr_t n_frames = stack->Length();
|
||||
String& url = String::Handle();
|
||||
String& function = String::Handle();
|
||||
Script& script = Script::Handle();
|
||||
for (int i = 0; i < n_frames; i++) {
|
||||
ActivationFrame* frame = stack->FrameAt(i);
|
||||
url ^= frame->SourceUrl();
|
||||
script ^= frame->SourceScript();
|
||||
function ^= frame->function().UserVisibleName();
|
||||
JSONObject jsobj(&jsarr);
|
||||
jsobj.AddProperty("name", function.ToCString());
|
||||
jsobj.AddProperty("url", url.ToCString());
|
||||
jsobj.AddProperty("script", script);
|
||||
jsobj.AddProperty("line", frame->LineNumber());
|
||||
jsobj.AddProperty("function", frame->function());
|
||||
jsobj.AddProperty("code", frame->code());
|
||||
@@ -239,6 +239,93 @@ static void HandleEcho(Isolate* isolate, JSONStream* js) {
|
||||
}
|
||||
|
||||
|
||||
#define CHECK_COLLECTION_ID_BOUNDS(collection, length, arg, id, js) \
|
||||
if (!GetIntegerId(arg, &id)) { \
|
||||
PrintError(js, "Must specify collection object id: %s/id", collection); \
|
||||
return; \
|
||||
} \
|
||||
if ((id < 0) || (id >= length)) { \
|
||||
PrintError(js, "%s id (%" Pd ") must be in [0, %" Pd ").", collection, id, \
|
||||
length); \
|
||||
return; \
|
||||
}
|
||||
|
||||
|
||||
static bool GetIntegerId(const char* s, intptr_t* id) {
|
||||
if ((s == NULL) || (*s == '\0')) {
|
||||
// Empty string.
|
||||
return false;
|
||||
}
|
||||
if (id == NULL) {
|
||||
// No id pointer.
|
||||
return false;
|
||||
}
|
||||
intptr_t r = 0;
|
||||
char* end_ptr = NULL;
|
||||
r = strtol(s, &end_ptr, 10);
|
||||
if (end_ptr == s) {
|
||||
// String was not advanced at all, cannot be valid.
|
||||
return false;
|
||||
}
|
||||
*id = r;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static void HandleClassesClosures(Isolate* isolate, const Class& cls,
|
||||
JSONStream* js) {
|
||||
const GrowableObjectArray& closures =
|
||||
GrowableObjectArray::Handle(cls.closures());
|
||||
intptr_t id;
|
||||
if (js->num_arguments() > 4) {
|
||||
PrintError(js, "Command too long");
|
||||
return;
|
||||
}
|
||||
CHECK_COLLECTION_ID_BOUNDS("closures", closures.Length(), js->GetArgument(3),
|
||||
id, js);
|
||||
Function& function = Function::Handle();
|
||||
function ^= closures.At(id);
|
||||
ASSERT(!function.IsNull());
|
||||
function.PrintToJSONStream(js, false);
|
||||
}
|
||||
|
||||
|
||||
static void HandleClassesFunctions(Isolate* isolate, const Class& cls,
|
||||
JSONStream* js) {
|
||||
const Array& functions =
|
||||
Array::Handle(cls.functions());
|
||||
intptr_t id;
|
||||
if (js->num_arguments() > 4) {
|
||||
PrintError(js, "Command too long");
|
||||
return;
|
||||
}
|
||||
CHECK_COLLECTION_ID_BOUNDS("functions", functions.Length(),
|
||||
js->GetArgument(3), id, js);
|
||||
Function& function = Function::Handle();
|
||||
function ^= functions.At(id);
|
||||
ASSERT(!function.IsNull());
|
||||
function.PrintToJSONStream(js, false);
|
||||
}
|
||||
|
||||
|
||||
static void HandleClassesFields(Isolate* isolate, const Class& cls,
|
||||
JSONStream* js) {
|
||||
const Array& fields =
|
||||
Array::Handle(cls.fields());
|
||||
intptr_t id;
|
||||
if (js->num_arguments() > 4) {
|
||||
PrintError(js, "Command too long");
|
||||
return;
|
||||
}
|
||||
CHECK_COLLECTION_ID_BOUNDS("fields", fields.Length(), js->GetArgument(3),
|
||||
id, js);
|
||||
Field& field = Field::Handle();
|
||||
field ^= fields.At(id);
|
||||
ASSERT(!field.IsNull());
|
||||
field.PrintToJSONStream(js, false);
|
||||
}
|
||||
|
||||
|
||||
static void HandleClasses(Isolate* isolate, JSONStream* js) {
|
||||
if (js->num_arguments() == 1) {
|
||||
ClassTable* table = isolate->class_table();
|
||||
@@ -246,14 +333,34 @@ static void HandleClasses(Isolate* isolate, JSONStream* js) {
|
||||
return;
|
||||
}
|
||||
ASSERT(js->num_arguments() >= 2);
|
||||
intptr_t id = atoi(js->GetArgument(1));
|
||||
intptr_t id;
|
||||
if (!GetIntegerId(js->GetArgument(1), &id)) {
|
||||
PrintError(js, "Must specify collection object id: /classes/id");
|
||||
return;
|
||||
}
|
||||
ClassTable* table = isolate->class_table();
|
||||
if (!table->IsValidIndex(id)) {
|
||||
Object::null_object().PrintToJSONStream(js, false);
|
||||
} else {
|
||||
Class& cls = Class::Handle(table->At(id));
|
||||
cls.PrintToJSONStream(js, false);
|
||||
PrintError(js, "%" Pd " is not a valid class id.", id);;
|
||||
return;
|
||||
}
|
||||
Class& cls = Class::Handle(table->At(id));
|
||||
if (js->num_arguments() == 2) {
|
||||
cls.PrintToJSONStream(js, false);
|
||||
return;
|
||||
} else if (js->num_arguments() >= 3) {
|
||||
const char* second = js->GetArgument(2);
|
||||
if (!strcmp(second, "closures")) {
|
||||
HandleClassesClosures(isolate, cls, js);
|
||||
} else if (!strcmp(second, "fields")) {
|
||||
HandleClassesFields(isolate, cls, js);
|
||||
} else if (!strcmp(second, "functions")) {
|
||||
HandleClassesFunctions(isolate, cls, js);
|
||||
} else {
|
||||
PrintError(js, "Invalid sub collection %s", second);
|
||||
}
|
||||
return;
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
|
||||
@@ -268,17 +375,109 @@ static void HandleLibrary(Isolate* isolate, JSONStream* js) {
|
||||
}
|
||||
|
||||
|
||||
static void HandleLibraries(Isolate* isolate, JSONStream* js) {
|
||||
// TODO(johnmccutchan): Support fields and functions on libraries.
|
||||
REQUIRE_COLLECTION_ID("libraries");
|
||||
const GrowableObjectArray& libs =
|
||||
GrowableObjectArray::Handle(isolate->object_store()->libraries());
|
||||
ASSERT(!libs.IsNull());
|
||||
intptr_t id = 0;
|
||||
CHECK_COLLECTION_ID_BOUNDS("libraries", libs.Length(), js->GetArgument(1),
|
||||
id, js);
|
||||
Library& lib = Library::Handle();
|
||||
lib ^= libs.At(id);
|
||||
ASSERT(!lib.IsNull());
|
||||
lib.PrintToJSONStream(js, false);
|
||||
}
|
||||
|
||||
|
||||
static void HandleObjects(Isolate* isolate, JSONStream* js) {
|
||||
REQUIRE_COLLECTION_ID("objects");
|
||||
ASSERT(js->num_arguments() >= 2);
|
||||
ObjectIdRing* ring = isolate->object_id_ring();
|
||||
ASSERT(ring != NULL);
|
||||
intptr_t id = atoi(js->GetArgument(1));
|
||||
intptr_t id = -1;
|
||||
if (!GetIntegerId(js->GetArgument(1), &id)) {
|
||||
Object::null_object().PrintToJSONStream(js, false);
|
||||
return;
|
||||
}
|
||||
Object& obj = Object::Handle(ring->GetObjectForId(id));
|
||||
obj.PrintToJSONStream(js, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void HandleScriptsEnumerate(Isolate* isolate, JSONStream* js) {
|
||||
JSONObject jsobj(js);
|
||||
jsobj.AddProperty("type", "ScriptList");
|
||||
{
|
||||
JSONArray members(&jsobj, "members");
|
||||
const GrowableObjectArray& libs =
|
||||
GrowableObjectArray::Handle(isolate->object_store()->libraries());
|
||||
int num_libs = libs.Length();
|
||||
Library &lib = Library::Handle();
|
||||
Script& script = Script::Handle();
|
||||
for (intptr_t i = 0; i < num_libs; i++) {
|
||||
lib ^= libs.At(i);
|
||||
ASSERT(!lib.IsNull());
|
||||
ASSERT(Smi::IsValid(lib.index()));
|
||||
const Array& loaded_scripts = Array::Handle(lib.LoadedScripts());
|
||||
ASSERT(!loaded_scripts.IsNull());
|
||||
intptr_t num_scripts = loaded_scripts.Length();
|
||||
for (intptr_t i = 0; i < num_scripts; i++) {
|
||||
script ^= loaded_scripts.At(i);
|
||||
members.AddValue(script);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void HandleScriptsFetch(Isolate* isolate, JSONStream* js) {
|
||||
const GrowableObjectArray& libs =
|
||||
GrowableObjectArray::Handle(isolate->object_store()->libraries());
|
||||
int num_libs = libs.Length();
|
||||
Library &lib = Library::Handle();
|
||||
Script& script = Script::Handle();
|
||||
String& url = String::Handle();
|
||||
const String& id = String::Handle(String::New(js->GetArgument(1)));
|
||||
ASSERT(!id.IsNull());
|
||||
// The id is the url of the script % encoded, decode it.
|
||||
String& requested_url = String::Handle(String::DecodeURI(id));
|
||||
for (intptr_t i = 0; i < num_libs; i++) {
|
||||
lib ^= libs.At(i);
|
||||
ASSERT(!lib.IsNull());
|
||||
ASSERT(Smi::IsValid(lib.index()));
|
||||
const Array& loaded_scripts = Array::Handle(lib.LoadedScripts());
|
||||
ASSERT(!loaded_scripts.IsNull());
|
||||
intptr_t num_scripts = loaded_scripts.Length();
|
||||
for (intptr_t i = 0; i < num_scripts; i++) {
|
||||
script ^= loaded_scripts.At(i);
|
||||
ASSERT(!script.IsNull());
|
||||
url ^= script.url();
|
||||
if (url.Equals(requested_url)) {
|
||||
script.PrintToJSONStream(js, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
PrintError(js, "Cannot find script %s\n", requested_url.ToCString());
|
||||
}
|
||||
|
||||
|
||||
static void HandleScripts(Isolate* isolate, JSONStream* js) {
|
||||
if (js->num_arguments() == 1) {
|
||||
// Enumerate all scripts.
|
||||
HandleScriptsEnumerate(isolate, js);
|
||||
} else if (js->num_arguments() == 2) {
|
||||
// Fetch specific script.
|
||||
HandleScriptsFetch(isolate, js);
|
||||
} else {
|
||||
PrintError(js, "Command too long");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void HandleDebug(Isolate* isolate, JSONStream* js) {
|
||||
if (js->num_arguments() == 1) {
|
||||
PrintError(js, "Must specify a subcommand");
|
||||
@@ -295,8 +494,11 @@ static void HandleDebug(Isolate* isolate, JSONStream* js) {
|
||||
|
||||
} else if (js->num_arguments() == 3) {
|
||||
// Print individual breakpoint.
|
||||
intptr_t id = atoi(js->GetArgument(2));
|
||||
SourceBreakpoint* bpt = isolate->debugger()->GetBreakpointById(id);
|
||||
intptr_t id = 0;
|
||||
SourceBreakpoint* bpt = NULL;
|
||||
if (GetIntegerId(js->GetArgument(2), &id)) {
|
||||
bpt = isolate->debugger()->GetBreakpointById(id);
|
||||
}
|
||||
if (bpt != NULL) {
|
||||
bpt->PrintToJSONStream(js);
|
||||
} else {
|
||||
@@ -324,10 +526,12 @@ static ServiceMessageHandlerEntry __message_handlers[] = {
|
||||
{ "classes", HandleClasses },
|
||||
{ "cpu", HandleCpu },
|
||||
{ "debug", HandleDebug },
|
||||
{ "libraries", HandleLibraries },
|
||||
{ "library", HandleLibrary },
|
||||
{ "name", HandleName },
|
||||
{ "objecthistogram", HandleObjectHistogram},
|
||||
{ "objects", HandleObjects },
|
||||
{ "scripts", HandleScripts },
|
||||
{ "stacktrace", HandleStackTrace },
|
||||
};
|
||||
|
||||
|
||||
@@ -54,6 +54,58 @@ static RawInstance* Eval(Dart_Handle lib, const char* expr) {
|
||||
}
|
||||
|
||||
|
||||
static RawInstance* EvalF(Dart_Handle lib, const char* fmt, ...) {
|
||||
Isolate* isolate = Isolate::Current();
|
||||
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
intptr_t len = OS::VSNPrint(NULL, 0, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
char* buffer = isolate->current_zone()->Alloc<char>(len + 1);
|
||||
va_list args2;
|
||||
va_start(args2, fmt);
|
||||
OS::VSNPrint(buffer, (len + 1), fmt, args2);
|
||||
va_end(args2);
|
||||
|
||||
return Eval(lib, buffer);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
static RawFunction* GetFunction(const Class& cls, const char* name) {
|
||||
const Function& result = Function::Handle(cls.LookupDynamicFunction(
|
||||
String::Handle(String::New(name))));
|
||||
EXPECT(!result.IsNull());
|
||||
return result.raw();
|
||||
}
|
||||
|
||||
|
||||
static RawFunction* GetStaticFunction(const Class& cls, const char* name) {
|
||||
const Function& result = Function::Handle(cls.LookupStaticFunction(
|
||||
String::Handle(String::New(name))));
|
||||
EXPECT(!result.IsNull());
|
||||
return result.raw();
|
||||
}
|
||||
|
||||
|
||||
static RawField* GetField(const Class& cls, const char* name) {
|
||||
const Field& field =
|
||||
Field::Handle(cls.LookupField(String::Handle(String::New(name))));
|
||||
EXPECT(!field.IsNull());
|
||||
return field.raw();
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
static RawClass* GetClass(const Library& lib, const char* name) {
|
||||
const Class& cls = Class::Handle(
|
||||
lib.LookupClass(String::Handle(Symbols::New(name))));
|
||||
EXPECT(!cls.IsNull()); // No ambiguity error expected.
|
||||
return cls.raw();
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE(Service_DebugBreakpoints) {
|
||||
const char* kScript =
|
||||
"var port;\n" // Set to our mock port by C++.
|
||||
@@ -146,4 +198,164 @@ TEST_CASE(Service_DebugBreakpoints) {
|
||||
handler.msg());
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE(Service_Classes) {
|
||||
const char* kScript =
|
||||
"var port;\n" // Set to our mock port by C++.
|
||||
"\n"
|
||||
"class A {\n"
|
||||
" var a;\n"
|
||||
" dynamic b() {}\n"
|
||||
" dynamic c() {\n"
|
||||
" var d = () { b(); };\n"
|
||||
" return d;\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"main() {\n"
|
||||
" var z = new A();\n"
|
||||
" var x = z.c();\n"
|
||||
" x();\n"
|
||||
"}";
|
||||
|
||||
Isolate* isolate = Isolate::Current();
|
||||
Dart_Handle h_lib = TestCase::LoadTestScript(kScript, NULL);
|
||||
EXPECT_VALID(h_lib);
|
||||
Library& lib = Library::Handle();
|
||||
lib ^= Api::UnwrapHandle(h_lib);
|
||||
EXPECT(!lib.IsNull());
|
||||
Dart_Handle result = Dart_Invoke(h_lib, NewString("main"), 0, NULL);
|
||||
EXPECT_VALID(result);
|
||||
const Class& class_a = Class::Handle(GetClass(lib, "A"));
|
||||
EXPECT(!class_a.IsNull());
|
||||
intptr_t cid = class_a.id();
|
||||
|
||||
// Build a mock message handler and wrap it in a dart port.
|
||||
ServiceTestMessageHandler handler;
|
||||
Dart_Port port_id = PortMap::CreatePort(&handler);
|
||||
Dart_Handle port =
|
||||
Api::NewHandle(isolate, DartLibraryCalls::NewSendPort(port_id));
|
||||
EXPECT_VALID(port);
|
||||
EXPECT_VALID(Dart_SetField(h_lib, NewString("port"), port));
|
||||
|
||||
Instance& service_msg = Instance::Handle();
|
||||
|
||||
// Request an invalid class id.
|
||||
service_msg = Eval(h_lib, "[port, ['classes', '999999'], [], []]");
|
||||
Service::HandleServiceMessage(isolate, service_msg);
|
||||
handler.HandleNextMessage();
|
||||
EXPECT_STREQ(
|
||||
"{\"type\":\"Error\",\"text\":\"999999 is not a valid class id.\","
|
||||
"\"message\":{\"arguments\":[\"classes\",\"999999\"],"
|
||||
"\"option_keys\":[],\"option_values\":[]}}", handler.msg());
|
||||
|
||||
// Request the class A over the service.
|
||||
service_msg = EvalF(h_lib, "[port, ['classes', '%" Pd "'], [], []]", cid);
|
||||
Service::HandleServiceMessage(isolate, service_msg);
|
||||
handler.HandleNextMessage();
|
||||
EXPECT_STREQ(
|
||||
"{\"type\":\"Class\",\"id\":\"classes\\/1009\",\"name\":\"A\","
|
||||
"\"user_name\":\"A\",\"implemented\":false,\"abstract\":false,"
|
||||
"\"patch\":false,\"finalized\":true,\"const\":false,\"super\":"
|
||||
"{\"type\":\"@Class\",\"id\":\"classes\\/35\",\"name\":\"Object\","
|
||||
"\"user_name\":\"Object\"},\"library\":{\"type\":\"@Library\",\"id\":"
|
||||
"\"libraries\\/12\",\"name\":\"\",\"user_name\":\"dart:test-lib\"},"
|
||||
"\"fields\":[{\"type\":\"@Field\",\"id\":\"classes\\/1009\\/fields\\/0\","
|
||||
"\"name\":\"a\",\"user_name\":\"a\",\"owner\":{\"type\":\"@Class\","
|
||||
"\"id\":\"classes\\/1009\",\"name\":\"A\",\"user_name\":\"A\"},"
|
||||
"\"declared_type\":{\"type\":\"@Class\",\"id\":\"classes\\/106\","
|
||||
"\"name\":\"dynamic\",\"user_name\":\"dynamic\"},\"static\":false,"
|
||||
"\"final\":false,\"const\":false}],\"functions\":["
|
||||
"{\"type\":\"@Function\",\"id\":\"classes\\/1009\\/functions\\/0\","
|
||||
"\"name\":\"get:a\",\"user_name\":\"A.a\"},{\"type\":\"@Function\","
|
||||
"\"id\":\"classes\\/1009\\/functions\\/1\",\"name\":\"set:a\","
|
||||
"\"user_name\":\"A.a=\"},{\"type\":\"@Function\",\"id\":"
|
||||
"\"classes\\/1009\\/functions\\/2\",\"name\":\"b\",\"user_name\":\"A.b\"}"
|
||||
",{\"type\":\"@Function\",\"id\":\"classes\\/1009\\/functions\\/3\","
|
||||
"\"name\":\"c\",\"user_name\":\"A.c\"},{\"type\":\"@Function\",\"id\":"
|
||||
"\"classes\\/1009\\/functions\\/4\",\"name\":\"A.\",\"user_name\":"
|
||||
"\"A.A\"}]}",
|
||||
handler.msg());
|
||||
|
||||
// Request function 0 from class A.
|
||||
service_msg = EvalF(h_lib, "[port, ['classes', '%" Pd "', 'functions', '0'],"
|
||||
"[], []]", cid);
|
||||
Service::HandleServiceMessage(isolate, service_msg);
|
||||
handler.HandleNextMessage();
|
||||
EXPECT_STREQ(
|
||||
"{\"type\":\"Function\",\"id\":\"classes\\/1009\\/functions\\/0\",\"name\":"
|
||||
"\"get:a\",\"user_name\":\"A.a\",\"is_static\":false,\"is_const\":false,"
|
||||
"\"is_optimizable\":true,\"is_inlinable\":false,\"kind\":"
|
||||
"\"implicit getter\",\"unoptimized_code\":{\"type\":\"null\"},"
|
||||
"\"usage_counter\":0,\"optimized_call_site_count\":0,\"code\":"
|
||||
"{\"type\":\"null\"},\"deoptimizations\":0}", handler.msg());
|
||||
|
||||
// Request field 0 from class A.
|
||||
service_msg = EvalF(h_lib, "[port, ['classes', '%" Pd "', 'fields', '0'],"
|
||||
"[], []]", cid);
|
||||
Service::HandleServiceMessage(isolate, service_msg);
|
||||
handler.HandleNextMessage();
|
||||
EXPECT_STREQ(
|
||||
"{\"type\":\"Field\",\"id\":\"classes\\/1009\\/fields\\/0\",\"name\":\"a\","
|
||||
"\"user_name\":\"a\",\"owner\":{\"type\":\"@Class\",\"id\":"
|
||||
"\"classes\\/1009\",\"name\":\"A\",\"user_name\":\"A\"},\"declared_type\":"
|
||||
"{\"type\":\"@Class\",\"id\":\"classes\\/106\",\"name\":\"dynamic\","
|
||||
"\"user_name\":\"dynamic\"},\"static\":false,\"final\":false,\"const\":"
|
||||
"false,\"guard_nullable\":true,\"guard_class\":{\"type\":\"@Class\","
|
||||
"\"id\":\"classes\\/105\",\"name\":\"Null\",\"user_name\":\"Null\"},"
|
||||
"\"guard_length\":\"variable\"}", handler.msg());
|
||||
|
||||
// Invalid sub command.
|
||||
service_msg = EvalF(h_lib, "[port, ['classes', '%" Pd "', 'huh', '0'],"
|
||||
"[], []]", cid);
|
||||
Service::HandleServiceMessage(isolate, service_msg);
|
||||
handler.HandleNextMessage();
|
||||
EXPECT_STREQ(
|
||||
"{\"type\":\"Error\",\"text\":\"Invalid sub collection huh\",\"message\":"
|
||||
"{\"arguments\":[\"classes\",\"1009\",\"huh\",\"0\"],\"option_keys\":[],"
|
||||
"\"option_values\":[]}}", handler.msg());
|
||||
|
||||
// Invalid field request.
|
||||
service_msg = EvalF(h_lib, "[port, ['classes', '%" Pd "', 'fields', '9'],"
|
||||
"[], []]", cid);
|
||||
Service::HandleServiceMessage(isolate, service_msg);
|
||||
handler.HandleNextMessage();
|
||||
EXPECT_STREQ(
|
||||
"{\"type\":\"Error\",\"text\":\"fields id (9) must be in [0, 1).\","
|
||||
"\"message\":{\"arguments\":[\"classes\",\"1009\",\"fields\",\"9\"],"
|
||||
"\"option_keys\":[],\"option_values\":[]}}", handler.msg());
|
||||
|
||||
// Invalid function request.
|
||||
service_msg = EvalF(h_lib, "[port, ['classes', '%" Pd "', 'functions', '9'],"
|
||||
"[], []]", cid);
|
||||
Service::HandleServiceMessage(isolate, service_msg);
|
||||
handler.HandleNextMessage();
|
||||
EXPECT_STREQ(
|
||||
"{\"type\":\"Error\",\"text\":\"functions id (9) must be in [0, 5).\","
|
||||
"\"message\":{\"arguments\":[\"classes\",\"1009\",\"functions\",\"9\"],"
|
||||
"\"option_keys\":[],\"option_values\":[]}}", handler.msg());
|
||||
|
||||
|
||||
// Invalid field subcommand.
|
||||
service_msg = EvalF(h_lib, "[port, ['classes', '%" Pd "', 'fields', '9', 'x']"
|
||||
",[], []]", cid);
|
||||
Service::HandleServiceMessage(isolate, service_msg);
|
||||
handler.HandleNextMessage();
|
||||
EXPECT_STREQ(
|
||||
"{\"type\":\"Error\",\"text\":\"Command too long\",\"message\":"
|
||||
"{\"arguments\":[\"classes\",\"1009\",\"fields\",\"9\",\"x\"],"
|
||||
"\"option_keys\":[],\"option_values\":[]}}",
|
||||
handler.msg());
|
||||
|
||||
// Invalid function request.
|
||||
service_msg = EvalF(h_lib, "[port, ['classes', '%" Pd "', 'functions', '9',"
|
||||
"'x'], [], []]", cid);
|
||||
Service::HandleServiceMessage(isolate, service_msg);
|
||||
handler.HandleNextMessage();
|
||||
EXPECT_STREQ(
|
||||
"{\"type\":\"Error\",\"text\":\"Command too long\",\"message\":"
|
||||
"{\"arguments\":[\"classes\",\"1009\",\"functions\",\"9\",\"x\"],"
|
||||
"\"option_keys\":[],\"option_values\":[]}}",
|
||||
handler.msg());
|
||||
}
|
||||
|
||||
} // namespace dart
|
||||
|
||||
@@ -10,16 +10,16 @@ import 'package:expect/expect.dart';
|
||||
|
||||
class NullCollectionTest extends VmServiceRequestHelper {
|
||||
NullCollectionTest(port, id, collection) :
|
||||
super('http://127.0.0.1:$port/isolates/$id/$collection/9999999');
|
||||
super('http://127.0.0.1:$port/$id/$collection/9999999');
|
||||
|
||||
onRequestCompleted(Map reply) {
|
||||
Expect.equals('null', reply['type']);
|
||||
Expect.equals('Error', reply['type']);
|
||||
}
|
||||
}
|
||||
|
||||
class BadCollectionTest extends VmServiceRequestHelper {
|
||||
BadCollectionTest(port, id, collection) :
|
||||
super('http://127.0.0.1:$port/isolates/$id/$collection');
|
||||
super('http://127.0.0.1:$port/$id/$collection');
|
||||
|
||||
onRequestCompleted(Map reply) {
|
||||
Expect.equals('Error', reply['type']);
|
||||
|
||||
@@ -10,7 +10,7 @@ import 'package:expect/expect.dart';
|
||||
|
||||
class NullCollectionTest extends VmServiceRequestHelper {
|
||||
NullCollectionTest(port, id) :
|
||||
super('http://127.0.0.1:$port/isolates/$id/objects/50');
|
||||
super('http://127.0.0.1:$port/$id/objects/50');
|
||||
|
||||
onRequestCompleted(Map reply) {
|
||||
Expect.equals('null', reply['type']);
|
||||
@@ -19,7 +19,7 @@ class NullCollectionTest extends VmServiceRequestHelper {
|
||||
|
||||
class BadCollectionTest extends VmServiceRequestHelper {
|
||||
BadCollectionTest(port, id) :
|
||||
super('http://127.0.0.1:$port/isolates/$id/objects');
|
||||
super('http://127.0.0.1:$port/$id/objects');
|
||||
|
||||
onRequestCompleted(Map reply) {
|
||||
Expect.equals('Error', reply['type']);
|
||||
|
||||
@@ -140,7 +140,7 @@ class BadBananaClassTest {
|
||||
|
||||
class ClassTableTest extends VmServiceRequestHelper {
|
||||
ClassTableTest(port, id) :
|
||||
super('http://127.0.0.1:$port/isolates/$id/classes/');
|
||||
super('http://127.0.0.1:$port/$id/classes/');
|
||||
|
||||
int banana_class_id;
|
||||
int bad_banana_class_id;
|
||||
|
||||
@@ -10,7 +10,7 @@ import 'package:expect/expect.dart';
|
||||
|
||||
class ClassTest extends VmServiceRequestHelper {
|
||||
ClassTest(port, id, classId) :
|
||||
super('http://127.0.0.1:$port/isolates/$id/classes/$classId');
|
||||
super('http://127.0.0.1:$port/$id/$classId');
|
||||
|
||||
onRequestCompleted(Map reply) {
|
||||
Expect.equals('Class', reply['type']);
|
||||
@@ -22,7 +22,7 @@ class ClassTest extends VmServiceRequestHelper {
|
||||
|
||||
class LibraryTest extends VmServiceRequestHelper {
|
||||
LibraryTest(port, id, libId) :
|
||||
super('http://127.0.0.1:$port/isolates/$id/objects/$libId');
|
||||
super('http://127.0.0.1:$port/$id/$libId');
|
||||
|
||||
int _classId;
|
||||
onRequestCompleted(Map reply) {
|
||||
@@ -37,7 +37,7 @@ class LibraryTest extends VmServiceRequestHelper {
|
||||
|
||||
class RootLibraryTest extends VmServiceRequestHelper {
|
||||
RootLibraryTest(port, id) :
|
||||
super('http://127.0.0.1:$port/isolates/$id/library');
|
||||
super('http://127.0.0.1:$port/$id/library');
|
||||
|
||||
int _libId;
|
||||
onRequestCompleted(Map reply) {
|
||||
|
||||
@@ -10,7 +10,7 @@ import 'package:expect/expect.dart';
|
||||
|
||||
class CodeATest extends VmServiceRequestHelper {
|
||||
CodeATest(port, id, codeId) :
|
||||
super('http://127.0.0.1:$port/isolates/$id/objects/$codeId');
|
||||
super('http://127.0.0.1:$port/$id/$codeId');
|
||||
|
||||
onRequestCompleted(Map reply) {
|
||||
Expect.equals('Code', reply['type']);
|
||||
@@ -21,7 +21,7 @@ class CodeATest extends VmServiceRequestHelper {
|
||||
|
||||
class CodeCTest extends VmServiceRequestHelper {
|
||||
CodeCTest(port, id, codeId) :
|
||||
super('http://127.0.0.1:$port/isolates/$id/objects/$codeId');
|
||||
super('http://127.0.0.1:$port/$id/$codeId');
|
||||
|
||||
onRequestCompleted(Map reply) {
|
||||
Expect.equals('Code', reply['type']);
|
||||
@@ -32,7 +32,7 @@ class CodeCTest extends VmServiceRequestHelper {
|
||||
|
||||
class StackTraceTest extends VmServiceRequestHelper {
|
||||
StackTraceTest(port, id) :
|
||||
super('http://127.0.0.1:$port/isolates/$id/stacktrace');
|
||||
super('http://127.0.0.1:$port/$id/stacktrace');
|
||||
|
||||
int _aId;
|
||||
int _cId;
|
||||
|
||||
@@ -9,7 +9,7 @@ import 'package:expect/expect.dart';
|
||||
|
||||
class EchoRequestTest extends VmServiceRequestHelper {
|
||||
EchoRequestTest(port, id) :
|
||||
super('http://127.0.0.1:$port/isolates/$id/_echo/foo/bar?a=b&k=&d=e&z=w');
|
||||
super('http://127.0.0.1:$port/$id/_echo/foo/bar?a=b&k=&d=e&z=w');
|
||||
|
||||
onRequestCompleted(Map reply) {
|
||||
Expect.equals('message', reply['type']);
|
||||
|
||||
@@ -10,7 +10,7 @@ import 'package:expect/expect.dart';
|
||||
|
||||
class MethodTest extends VmServiceRequestHelper {
|
||||
MethodTest(port, id, functionId) :
|
||||
super('http://127.0.0.1:$port/isolates/$id/objects/$functionId');
|
||||
super('http://127.0.0.1:$port/$id/$functionId');
|
||||
onRequestCompleted(Map reply) {
|
||||
Expect.equals('Function', reply['type']);
|
||||
Expect.equals('C.c', reply['user_name']);
|
||||
@@ -20,7 +20,7 @@ class MethodTest extends VmServiceRequestHelper {
|
||||
|
||||
class FunctionTest extends VmServiceRequestHelper {
|
||||
FunctionTest(port, id, functionId) :
|
||||
super('http://127.0.0.1:$port/isolates/$id/objects/$functionId');
|
||||
super('http://127.0.0.1:$port/$id/$functionId');
|
||||
|
||||
onRequestCompleted(Map reply) {
|
||||
Expect.equals('Function', reply['type']);
|
||||
@@ -31,7 +31,7 @@ class FunctionTest extends VmServiceRequestHelper {
|
||||
|
||||
class StackTraceTest extends VmServiceRequestHelper {
|
||||
StackTraceTest(port, id) :
|
||||
super('http://127.0.0.1:$port/isolates/$id/stacktrace');
|
||||
super('http://127.0.0.1:$port/$id/stacktrace');
|
||||
|
||||
int _aId;
|
||||
int _cId;
|
||||
|
||||
@@ -10,7 +10,7 @@ import 'package:expect/expect.dart';
|
||||
|
||||
class LibraryTest extends VmServiceRequestHelper {
|
||||
LibraryTest(port, id, libId) :
|
||||
super('http://127.0.0.1:$port/isolates/$id/objects/$libId');
|
||||
super('http://127.0.0.1:$port/$id/$libId');
|
||||
|
||||
onRequestCompleted(Map reply) {
|
||||
Expect.equals('Library', reply['type']);
|
||||
@@ -20,7 +20,7 @@ class LibraryTest extends VmServiceRequestHelper {
|
||||
|
||||
class RootLibraryTest extends VmServiceRequestHelper {
|
||||
RootLibraryTest(port, id) :
|
||||
super('http://127.0.0.1:$port/isolates/$id/library');
|
||||
super('http://127.0.0.1:$port/$id/library');
|
||||
|
||||
int _libId;
|
||||
onRequestCompleted(Map reply) {
|
||||
|
||||
@@ -9,7 +9,7 @@ import 'package:expect/expect.dart';
|
||||
|
||||
class StacktraceTest extends VmServiceRequestHelper {
|
||||
StacktraceTest(port, id) :
|
||||
super('http://127.0.0.1:$port/isolates/$id/stacktrace');
|
||||
super('http://127.0.0.1:$port/$id/stacktrace');
|
||||
|
||||
onRequestCompleted(Map reply) {
|
||||
Expect.equals('StackTrace', reply['type'], 'Not a StackTrace message.');
|
||||
|
||||
@@ -255,7 +255,7 @@ class ClassTableHelper {
|
||||
|
||||
class FieldRequestHelper extends VmServiceRequestHelper {
|
||||
FieldRequestHelper(port, isolate_id, field_id) :
|
||||
super('http://127.0.0.1:$port/isolates/$isolate_id/objects/$field_id');
|
||||
super('http://127.0.0.1:$port/$isolate_id/$field_id');
|
||||
Map field;
|
||||
onRequestCompleted(Map reply) {
|
||||
Expect.equals('Field', reply['type']);
|
||||
@@ -269,7 +269,7 @@ class ClassFieldRequestHelper extends VmServiceRequestHelper {
|
||||
int port_;
|
||||
int isolate_id_;
|
||||
ClassFieldRequestHelper(port, isolate_id, class_id, this.fieldNames) :
|
||||
super('http://127.0.0.1:$port/isolates/$isolate_id/classes/$class_id') {
|
||||
super('http://127.0.0.1:$port/$isolate_id/$class_id') {
|
||||
port_ = port;
|
||||
isolate_id_ = isolate_id;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import 'package:expect/expect.dart';
|
||||
|
||||
class ClassTableTest extends VmServiceRequestHelper {
|
||||
ClassTableTest(port, id) :
|
||||
super('http://127.0.0.1:$port/isolates/$id/classes');
|
||||
super('http://127.0.0.1:$port/$id/classes');
|
||||
|
||||
onRequestCompleted(Map reply) {
|
||||
ClassTableHelper helper = new ClassTableHelper(reply);
|
||||
|
||||
Reference in New Issue
Block a user