Version 1.20.0-dev.1.0
Merge 7b29f2b79c9d8bc36aab1e9418a9377ac5662382 into dev
diff --git a/DEPS b/DEPS
index 2d7bfbf..e231f85 100644
--- a/DEPS
+++ b/DEPS
@@ -55,8 +55,8 @@
"dart2js_info_rev" : "@0a221eaf16aec3879c45719de656680ccb80d8a1",
"dart_services_rev" : "@7aea2574e6f3924bf409a80afb8ad52aa2be4f97",
"dart_style_tag": "@0.2.9+1",
- "dartdoc_tag" : "@v0.9.6+2",
- "dev_compiler_rev": "@fa084164b620ea75cd2008c9dc317655a045ad6d",
+ "dartdoc_tag" : "@v0.9.7+2",
+ "dev_compiler_rev": "@d6371ee44e8f119b847c1f4cc29957bff471057b",
"fixnum_tag": "@0.10.5",
"func_rev": "@8d4aea75c21be2179cb00dc2b94a71414653094e",
"glob_rev": "@704cf75e4f26b417505c5c611bdaacd8808467dd",
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 866f58a..12b6378 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -32,7 +32,6 @@
import 'package:analyzer/source/pub_package_map_provider.dart';
import 'package:analyzer/src/context/builder.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
-import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/java_io.dart';
@@ -46,7 +45,6 @@
import 'package:analyzer/src/util/glob.dart';
import 'package:analyzer/task/dart.dart';
import 'package:plugin/plugin.dart';
-import 'package:yaml/yaml.dart';
typedef void OptionUpdater(AnalysisOptionsImpl options);
@@ -1596,14 +1594,10 @@
@override
AnalysisContext addContext(
Folder folder, AnalysisOptions options, FolderDisposition disposition) {
- InternalAnalysisContext context =
- AnalysisEngine.instance.createAnalysisContext();
- context.contentCache = analysisServer.overlayState;
- analysisServer.folderMap[folder] = context;
- context.fileResolverProvider = analysisServer.fileResolverProvider;
- context.sourceFactory =
- _createSourceFactory(context, options, disposition, folder);
- context.analysisOptions = options;
+ ContextBuilder builder = createContextBuilder(folder, options);
+ AnalysisContext context = builder.buildContext(folder.path);
+
+ // TODO(brianwilkerson) Move bundle discovery into ContextBuilder
if (analysisServer.options.enablePubSummaryManager) {
List<LinkedPubPackage> linkedBundles =
analysisServer.pubSummaryManager.getLinkedBundles(context);
@@ -1613,11 +1607,12 @@
store.addBundle(null, package.unlinked);
store.addBundle(null, package.linked);
}
- context.resultProvider =
+ (context as InternalAnalysisContext).resultProvider =
new InputPackagesResultProvider(context, store);
}
}
+ analysisServer.folderMap[folder] = context;
analysisServer._onContextsChangedController
.add(new ContextsChangedEvent(added: [context]));
analysisServer.schedulePerformAnalysisOperation(context);
@@ -1646,6 +1641,32 @@
analysisServer._computingPackageMap(computing);
@override
+ ContextBuilder createContextBuilder(Folder folder, AnalysisOptions options) {
+ String defaultPackageFilePath = null;
+ String defaultPackagesDirectoryPath = null;
+ String path = (analysisServer.contextManager as ContextManagerImpl)
+ .normalizedPackageRoots[folder.path];
+ if (path != null) {
+ Resource resource = resourceProvider.getResource(path);
+ if (resource.exists) {
+ if (resource is File) {
+ defaultPackageFilePath = path;
+ } else {
+ defaultPackagesDirectoryPath = path;
+ }
+ }
+ }
+
+ ContextBuilder builder = new ContextBuilder(resourceProvider,
+ analysisServer.sdkManager, analysisServer.overlayState);
+ builder.defaultOptions = options;
+ builder.fileResolverProvider = analysisServer.fileResolverProvider;
+ builder.defaultPackageFilePath = defaultPackageFilePath;
+ builder.defaultPackagesDirectoryPath = defaultPackagesDirectoryPath;
+ return builder;
+ }
+
+ @override
void moveContext(Folder from, Folder to) {
// There is nothing to do.
// This method is mostly for tests.
@@ -1671,61 +1692,6 @@
.add(new ContextsChangedEvent(changed: [context]));
analysisServer.schedulePerformAnalysisOperation(context);
}
-
- /**
- * Set up a [SourceFactory] that resolves packages as appropriate for the
- * given [disposition].
- */
- SourceFactory _createSourceFactory(InternalAnalysisContext context,
- AnalysisOptions options, FolderDisposition disposition, Folder folder) {
- List<UriResolver> resolvers = [];
- List<UriResolver> packageUriResolvers =
- disposition.createPackageUriResolvers(resourceProvider);
-
- // If no embedded URI resolver was provided, defer to a locator-backed one.
- SdkExtensionFinder extFinder =
- disposition.getSdkExtensionFinder(resourceProvider);
- List<String> extFilePaths = extFinder.extensionFilePaths;
- EmbedderYamlLocator locator =
- disposition.getEmbedderLocator(resourceProvider);
- Map<Folder, YamlMap> embedderYamls = locator.embedderYamls;
- EmbedderSdk embedderSdk = new EmbedderSdk(resourceProvider, embedderYamls);
- if (embedderSdk.libraryMap.size() == 0) {
- // There was no embedder file, or the file was empty, so used the default
- // SDK.
- resolvers.add(new DartUriResolver(
- analysisServer.sdkManager.getSdkForOptions(options)));
- } else {
- // The embedder file defines an alternate SDK, so use it.
- List<String> paths = <String>[];
- for (Folder folder in embedderYamls.keys) {
- paths.add(folder
- .getChildAssumingFile(EmbedderYamlLocator.EMBEDDER_FILE_NAME)
- .path);
- }
- paths.addAll(extFilePaths);
- DartSdk dartSdk = analysisServer.sdkManager
- .getSdk(new SdkDescription(paths, options), () {
- if (extFilePaths.isNotEmpty) {
- embedderSdk.addExtensions(extFinder.urlMappings);
- }
- embedderSdk.analysisOptions = options;
- // TODO(brianwilkerson) Enable summary use after we have decided where
- // summary files for embedder files will live.
- embedderSdk.useSummary = false;
- return embedderSdk;
- });
- resolvers.add(new DartUriResolver(dartSdk));
- }
-
- resolvers.addAll(packageUriResolvers);
- UriResolver fileResolver;
- if (context.fileResolverProvider != null) {
- fileResolver = context.fileResolverProvider(folder);
- }
- resolvers.add(fileResolver ?? new ResourceUriResolver(resourceProvider));
- return new SourceFactory(resolvers, disposition.packages);
- }
}
/**
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index fd35213..5c47909 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -23,7 +23,6 @@
import 'package:analyzer/source/sdk_ext.dart';
import 'package:analyzer/src/context/builder.dart';
import 'package:analyzer/src/context/context.dart' as context;
-import 'package:analyzer/src/context/source.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/java_engine.dart';
@@ -343,6 +342,12 @@
void computingPackageMap(bool computing);
/**
+ * Create and return a context builder that can be used to create a context
+ * for the files in the given [folder] when analyzed using the given [options].
+ */
+ ContextBuilder createContextBuilder(Folder folder, AnalysisOptions options);
+
+ /**
* Called when the context manager changes the folder with which a context is
* associated. Currently this is mostly FYI, and used only in tests.
*/
@@ -899,55 +904,14 @@
// Check to see if this is the .packages file for this context and if so,
// update the context's source factory.
if (absolutePathContext.basename(path) == PACKAGE_SPEC_NAME) {
- File packagespec = resourceProvider.getFile(path);
- if (packagespec.exists) {
- // Locate embedder yamls for this .packages file.
- // If any embedder libs are contributed and this context does not
- // have an embedded URI resolver, we need to create a new context.
-
- List<int> bytes = packagespec.readAsStringSync().codeUnits;
- Map<String, Uri> packages =
- pkgfile.parse(bytes, new Uri.file(packagespec.path));
-
- Map<String, List<Folder>> packageMap =
- new PackagesFileDisposition(new MapPackages(packages))
- .buildPackageMap(resourceProvider);
- Map<Folder, YamlMap> embedderYamls =
- new EmbedderYamlLocator(packageMap).embedderYamls;
-
- SourceFactory sourceFactory = info.context.sourceFactory;
-
- // Check for library embedders.
- if (embedderYamls.values.any(definesEmbeddedLibs)) {
- // If there is no embedded URI resolver, a new source factory needs to
- // be recreated.
- if (sourceFactory is SourceFactoryImpl) {
- // Get all but the dart: Uri resolver.
- List<UriResolver> resolvers = sourceFactory.resolvers
- .where((r) => r is! DartUriResolver)
- .toList();
- // Add an embedded URI resolver in its place.
- resolvers.add(new DartUriResolver(
- new EmbedderSdk(resourceProvider, embedderYamls)));
-
- // Set a new source factory.
- SourceFactoryImpl newFactory = sourceFactory.clone();
- newFactory.resolvers.clear();
- newFactory.resolvers.addAll(resolvers);
- info.context.sourceFactory = newFactory;
- return;
- }
- }
-
- // Next check for package URI updates.
- if (info.isPathToPackageDescription(path)) {
- Packages packages = _readPackagespec(packagespec);
- if (packages != null) {
- _updateContextPackageUriResolver(
- folder, new PackagesFileDisposition(packages));
- }
- }
- }
+ String contextRoot = info.folder.path;
+ ContextBuilder builder =
+ callbacks.createContextBuilder(info.folder, defaultContextOptions);
+ AnalysisOptions options =
+ builder.getAnalysisOptions(info.context, contextRoot);
+ SourceFactory factory = builder.createSourceFactory(contextRoot, options);
+ info.context.analysisOptions = options;
+ info.context.sourceFactory = factory;
}
}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index b64f428..12b27fa 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -697,8 +697,8 @@
}
}
// prepare location for a new constructor
- _ClassMemberLocation targetLocation =
- _prepareNewConstructorLocation(classDeclaration);
+ ClassMemberLocation targetLocation =
+ utils.prepareNewConstructorLocation(classDeclaration);
// build constructor source
SourceBuilder sb = new SourceBuilder(file, targetLocation.offset);
{
@@ -741,8 +741,8 @@
if (targetTypeNode is! ClassDeclaration) {
return;
}
- _ClassMemberLocation targetLocation =
- _prepareNewConstructorLocation(targetTypeNode);
+ ClassMemberLocation targetLocation =
+ utils.prepareNewConstructorLocation(targetTypeNode);
String targetFile = targetElement.source.fullName;
// build method source
SourceBuilder sb = new SourceBuilder(targetFile, targetLocation.offset);
@@ -797,8 +797,8 @@
if (targetTypeNode is! ClassDeclaration) {
return;
}
- _ClassMemberLocation targetLocation =
- _prepareNewConstructorLocation(targetTypeNode);
+ ClassMemberLocation targetLocation =
+ utils.prepareNewConstructorLocation(targetTypeNode);
String targetFile = targetElement.source.fullName;
// build method source
SourceBuilder sb = new SourceBuilder(targetFile, targetLocation.offset);
@@ -935,8 +935,8 @@
argumentsBuffer.append(parameterName);
}
// add proposal
- _ClassMemberLocation targetLocation =
- _prepareNewConstructorLocation(targetClassNode);
+ ClassMemberLocation targetLocation =
+ utils.prepareNewConstructorLocation(targetClassNode);
SourceBuilder sb = new SourceBuilder(file, targetLocation.offset);
{
sb.append(targetLocation.prefix);
@@ -1017,8 +1017,8 @@
}
ClassDeclaration targetClassNode = targetTypeNode;
// prepare location
- _ClassMemberLocation targetLocation =
- _prepareNewFieldLocation(targetClassNode);
+ ClassMemberLocation targetLocation =
+ utils.prepareNewFieldLocation(targetClassNode);
// build method source
String targetFile = targetClassElement.source.fullName;
SourceBuilder sb = new SourceBuilder(targetFile, targetLocation.offset);
@@ -1150,8 +1150,8 @@
}
ClassDeclaration targetClassNode = targetTypeNode;
// prepare location
- _ClassMemberLocation targetLocation =
- _prepareNewGetterLocation(targetClassNode);
+ ClassMemberLocation targetLocation =
+ utils.prepareNewGetterLocation(targetClassNode);
// build method source
String targetFile = targetClassElement.source.fullName;
SourceBuilder sb = new SourceBuilder(targetFile, targetLocation.offset);
@@ -1278,7 +1278,7 @@
// EOL management
bool isFirst = true;
void addEolIfNotFirst() {
- if (!isFirst || _isClassWithEmptyBody(targetClass)) {
+ if (!isFirst || utils.isClassWithEmptyBody(targetClass)) {
sb.append(eol);
}
isFirst = false;
@@ -2734,64 +2734,6 @@
}
/**
- * Return `true` if the given [classDeclaration] has open '{' and close '}'
- * at the same line, e.g. `class X {}`.
- */
- bool _isClassWithEmptyBody(ClassDeclaration classDeclaration) {
- return utils.getLineThis(classDeclaration.leftBracket.offset) ==
- utils.getLineThis(classDeclaration.rightBracket.offset);
- }
-
- _ClassMemberLocation _prepareNewClassMemberLocation(
- ClassDeclaration classDeclaration,
- bool shouldSkip(ClassMember existingMember)) {
- String indent = utils.getIndent(1);
- // Find the last target member.
- ClassMember targetMember = null;
- List<ClassMember> members = classDeclaration.members;
- for (ClassMember member in members) {
- if (shouldSkip(member)) {
- targetMember = member;
- } else {
- break;
- }
- }
- // After the last target member.
- if (targetMember != null) {
- return new _ClassMemberLocation(eol + eol + indent, targetMember.end, '');
- }
- // At the beginning of the class.
- String suffix = members.isNotEmpty ||
- _isClassWithEmptyBody(classDeclaration) ? eol : '';
- return new _ClassMemberLocation(
- eol + indent, classDeclaration.leftBracket.end, suffix);
- }
-
- _ClassMemberLocation _prepareNewConstructorLocation(
- ClassDeclaration classDeclaration) {
- return _prepareNewClassMemberLocation(
- classDeclaration,
- (member) =>
- member is FieldDeclaration || member is ConstructorDeclaration);
- }
-
- _ClassMemberLocation _prepareNewFieldLocation(
- ClassDeclaration classDeclaration) {
- return _prepareNewClassMemberLocation(
- classDeclaration, (member) => member is FieldDeclaration);
- }
-
- _ClassMemberLocation _prepareNewGetterLocation(
- ClassDeclaration classDeclaration) {
- return _prepareNewClassMemberLocation(
- classDeclaration,
- (member) =>
- member is FieldDeclaration ||
- member is ConstructorDeclaration ||
- member is MethodDeclaration && member.isGetter);
- }
-
- /**
* Removes any [ParenthesizedExpression] enclosing [expr].
*
* [exprPrecedence] - the effective precedence of [expr].
@@ -2910,17 +2852,6 @@
}
/**
- * Describes the location for a newly created [ClassMember].
- */
-class _ClassMemberLocation {
- final String prefix;
- final int offset;
- final String suffix;
-
- _ClassMemberLocation(this.prefix, this.offset, this.suffix);
-}
-
-/**
* Helper for finding [Element] with name closest to the given.
*/
class _ClosestElementFinder {
diff --git a/pkg/analysis_server/lib/src/services/correction/util.dart b/pkg/analysis_server/lib/src/services/correction/util.dart
index 445aab2..8a357d6 100644
--- a/pkg/analysis_server/lib/src/services/correction/util.dart
+++ b/pkg/analysis_server/lib/src/services/correction/util.dart
@@ -663,6 +663,17 @@
return expression;
}
+/**
+ * Describes the location for a newly created [ClassMember].
+ */
+class ClassMemberLocation {
+ final String prefix;
+ final int offset;
+ final String suffix;
+
+ ClassMemberLocation(this.prefix, this.offset, this.suffix);
+}
+
class CorrectionUtils {
final CompilationUnit unit;
@@ -1214,6 +1225,15 @@
_invertCondition0(expression)._source;
/**
+ * Return `true` if the given [classDeclaration] has open '{' and close '}'
+ * at the same line, e.g. `class X {}`.
+ */
+ bool isClassWithEmptyBody(ClassDeclaration classDeclaration) {
+ return getLineThis(classDeclaration.leftBracket.offset) ==
+ getLineThis(classDeclaration.rightBracket.offset);
+ }
+
+ /**
* @return <code>true</code> if selection range contains only whitespace or comments
*/
bool isJustWhitespaceOrComment(SourceRange range) {
@@ -1226,6 +1246,57 @@
return TokenUtils.getTokens(trimmedText).isEmpty;
}
+ ClassMemberLocation prepareNewClassMemberLocation(
+ ClassDeclaration classDeclaration,
+ bool shouldSkip(ClassMember existingMember)) {
+ String indent = getIndent(1);
+ // Find the last target member.
+ ClassMember targetMember = null;
+ List<ClassMember> members = classDeclaration.members;
+ for (ClassMember member in members) {
+ if (shouldSkip(member)) {
+ targetMember = member;
+ } else {
+ break;
+ }
+ }
+ // After the last target member.
+ if (targetMember != null) {
+ return new ClassMemberLocation(
+ endOfLine + endOfLine + indent, targetMember.end, '');
+ }
+ // At the beginning of the class.
+ String suffix = members.isNotEmpty || isClassWithEmptyBody(classDeclaration)
+ ? endOfLine
+ : '';
+ return new ClassMemberLocation(
+ endOfLine + indent, classDeclaration.leftBracket.end, suffix);
+ }
+
+ ClassMemberLocation prepareNewConstructorLocation(
+ ClassDeclaration classDeclaration) {
+ return prepareNewClassMemberLocation(
+ classDeclaration,
+ (member) =>
+ member is FieldDeclaration || member is ConstructorDeclaration);
+ }
+
+ ClassMemberLocation prepareNewFieldLocation(
+ ClassDeclaration classDeclaration) {
+ return prepareNewClassMemberLocation(
+ classDeclaration, (member) => member is FieldDeclaration);
+ }
+
+ ClassMemberLocation prepareNewGetterLocation(
+ ClassDeclaration classDeclaration) {
+ return prepareNewClassMemberLocation(
+ classDeclaration,
+ (member) =>
+ member is FieldDeclaration ||
+ member is ConstructorDeclaration ||
+ member is MethodDeclaration && member.isGetter);
+ }
+
/**
* Returns the source with indentation changed from [oldIndent] to
* [newIndent], keeping indentation of lines relative to each other.
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart
index 23e0342..72a29ce 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart
@@ -16,6 +16,7 @@
import 'package:analysis_server/src/services/refactoring/rename.dart';
import 'package:analysis_server/src/services/search/hierarchy.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/generated/java_core.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -52,17 +53,19 @@
@override
Future fillChange() async {
- if (!element.isSynthetic) {
- // prepare references
- List<SearchMatch> matches = await searchEngine.searchReferences(element);
- List<SourceReference> references = getSourceReferences(matches);
- // append declaration
+ // prepare references
+ List<SearchMatch> matches = await searchEngine.searchReferences(element);
+ List<SourceReference> references = getSourceReferences(matches);
+ // append declaration
+ if (element.isSynthetic) {
+ _replaceSynthetic();
+ } else {
references.add(_createDeclarationReference());
- // update references
- String replacement = newName.isEmpty ? '' : '.$newName';
- for (SourceReference reference in references) {
- reference.addEdit(change, replacement);
- }
+ }
+ // update references
+ String replacement = newName.isEmpty ? '' : '.$newName';
+ for (SourceReference reference in references) {
+ reference.addEdit(change, replacement);
}
}
@@ -95,4 +98,21 @@
true,
true));
}
+
+ void _replaceSynthetic() {
+ ClassElement classElement = element.enclosingElement;
+ ClassDeclaration classNode = classElement.computeNode();
+ CorrectionUtils utils = new CorrectionUtils(classNode.parent);
+ ClassMemberLocation location =
+ utils.prepareNewConstructorLocation(classNode);
+ doSourceChange_addElementEdit(
+ change,
+ classElement,
+ new SourceEdit(
+ location.offset,
+ 0,
+ location.prefix +
+ '${classElement.name}.$newName();' +
+ location.suffix));
+ }
}
diff --git a/pkg/analysis_server/lib/src/status/get_handler.dart b/pkg/analysis_server/lib/src/status/get_handler.dart
index d3a8cdf..157225f 100644
--- a/pkg/analysis_server/lib/src/status/get_handler.dart
+++ b/pkg/analysis_server/lib/src/status/get_handler.dart
@@ -486,10 +486,6 @@
if (unit != null) {
return unit;
}
- unit = entry.getValue(RESOLVED_UNIT13);
- if (unit != null) {
- return unit;
- }
return entry.getValue(RESOLVED_UNIT);
}
@@ -562,7 +558,6 @@
results.add(RESOLVED_UNIT10);
results.add(RESOLVED_UNIT11);
results.add(RESOLVED_UNIT12);
- results.add(RESOLVED_UNIT13);
results.add(RESOLVED_UNIT);
results.add(STRONG_MODE_ERRORS);
results.add(USED_IMPORTED_ELEMENTS);
diff --git a/pkg/analysis_server/test/analysis_abstract.dart b/pkg/analysis_server/test/analysis_abstract.dart
index b76102d..0db5841 100644
--- a/pkg/analysis_server/test/analysis_abstract.dart
+++ b/pkg/analysis_server/test/analysis_abstract.dart
@@ -125,6 +125,7 @@
//
// Create server
//
+ MockSdk sdk = new MockSdk(resourceProvider: resourceProvider);
return new AnalysisServer(
serverChannel,
resourceProvider,
@@ -132,7 +133,7 @@
index,
serverPlugin,
new AnalysisServerOptions(),
- new DartSdkManager('', false, (_) => new MockSdk()),
+ new DartSdkManager('/', false, (_) => sdk),
InstrumentationService.NULL_SERVICE);
}
@@ -143,10 +144,10 @@
/**
* Creates a project `/project`.
*/
- void createProject() {
+ void createProject({Map<String, String> packageRoots}) {
resourceProvider.newFolder(projectPath);
Request request =
- new AnalysisSetAnalysisRootsParams([projectPath], []).toRequest('0');
+ new AnalysisSetAnalysisRootsParams([projectPath], [], packageRoots: packageRoots).toRequest('0');
handleSuccessfulRequest(request, handler: analysisHandler);
}
diff --git a/pkg/analysis_server/test/analysis_server_test.dart b/pkg/analysis_server/test/analysis_server_test.dart
index 1c2e212..af36f04 100644
--- a/pkg/analysis_server/test/analysis_server_test.dart
+++ b/pkg/analysis_server/test/analysis_server_test.dart
@@ -137,6 +137,7 @@
manager.processPlugins([plugin]);
channel = new MockServerChannel();
resourceProvider = new MemoryResourceProvider();
+ MockSdk sdk = new MockSdk(resourceProvider: resourceProvider);
packageMapProvider = new MockPackageMapProvider();
server = new AnalysisServer(
channel,
@@ -145,7 +146,7 @@
null,
plugin,
new AnalysisServerOptions(),
- new DartSdkManager('', false, (_) => new MockSdk()),
+ new DartSdkManager('/', false, (_) => sdk),
InstrumentationService.NULL_SERVICE,
rethrowExceptions: true);
processRequiredPlugins();
@@ -286,26 +287,6 @@
expect(pair.source, isNull);
}
- test_getContextSourcePair_package_inRoot() {
- String rootPath = '/my_package';
- String filePath = rootPath + '/lib/file.dart';
- Folder rootFolder = resourceProvider.newFolder(rootPath);
- resourceProvider.newFile(filePath, 'library lib;');
-
- packageMapProvider.packageMap = <String, List<Folder>>{
- 'my_package': <Folder>[rootFolder]
- };
- // create contexts
- server.setAnalysisRoots('0', [rootPath], [], {});
- // get pair
- ContextSourcePair pair = server.getContextSourcePair(filePath);
- _assertContextOfFolder(pair.context, rootPath);
- Source source = pair.source;
- expect(source, isNotNull);
- expect(source.uri.scheme, 'package');
- expect(source.fullName, filePath);
- }
-
test_getContextSourcePair_simple() {
String dirPath = '/dir';
String filePath = dirPath + '/file.dart';
@@ -321,6 +302,23 @@
expect(source.fullName, filePath);
}
+ test_getContextSourcePair_withPackagesFile() {
+ String dirPath = '/dir';
+ String packagesFilePath = dirPath + '/.packages';
+ resourceProvider.newFile(packagesFilePath, 'dir:lib/');
+ String filePath = dirPath + '/lib/file.dart';
+ resourceProvider.newFile(filePath, 'library lib;');
+ // create contexts
+ server.setAnalysisRoots('0', [dirPath], [], {});
+ // get pair
+ ContextSourcePair pair = server.getContextSourcePair(filePath);
+ _assertContextOfFolder(pair.context, dirPath);
+ Source source = pair.source;
+ expect(source, isNotNull);
+ expect(source.uri.scheme, 'package');
+ expect(source.fullName, filePath);
+ }
+
/**
* Test that having multiple analysis contexts analyze the same file doesn't
* cause that file to receive duplicate notifications when it's modified.
diff --git a/pkg/analysis_server/test/completion_test.dart b/pkg/analysis_server/test/completion_test.dart
index 2a453eb..70ac854 100644
--- a/pkg/analysis_server/test/completion_test.dart
+++ b/pkg/analysis_server/test/completion_test.dart
@@ -2664,7 +2664,7 @@
"8-null"
],
failingTests: '234567'); //TODO(jwren) 234 failing as correct selection
- // offset assertions can't be passed into buildTests(..)
+ // offset assertions can't be passed into buildTests(..)
// keywords
buildTests('test018', '''!1part !2of foo;''', <String>["1+part", "2+of"],
@@ -2850,7 +2850,7 @@
// test analysis of untyped fields and top-level vars
buildTests('test035', '''class Y {final x='hi';mth() {x.!1length;}}''',
- <String>["1+length"]);
+ <String>["1+length"], failingTests: '1');
// TODO(scheglov) decide what to do with Type for untyped field (not
// supported by the new store)
@@ -2905,8 +2905,8 @@
failingTests: '2');
// test analysis of untyped fields and top-level vars
- buildTests('test039', '''class X{}var x = null as !1X;''',
- <String>["1-void"]);
+ buildTests(
+ 'test039', '''class X{}var x = null as !1X;''', <String>["1-void"]);
// test arg lists with named params
buildTests('test040', '''m(){f(a, b, {x1, x2, y}) {};f(1, 2, !1)!2;}''',
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index 41b0983..1aa02fe 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -1820,8 +1820,8 @@
processRequiredPlugins();
resourceProvider = new MemoryResourceProvider();
packageMapProvider = new MockPackageMapProvider();
- DartSdkManager sdkManager =
- new DartSdkManager('', false, (_) => new MockSdk());
+ DartSdk sdk = new MockSdk(resourceProvider: resourceProvider);
+ DartSdkManager sdkManager = new DartSdkManager('/', false, (_) => sdk);
manager = new ContextManagerImpl(
resourceProvider,
sdkManager,
@@ -2705,6 +2705,15 @@
}
@override
+ ContextBuilder createContextBuilder(Folder folder, AnalysisOptions options) {
+ DartSdkManager sdkManager = new DartSdkManager('/', false, null);
+ ContextBuilder builder =
+ new ContextBuilder(resourceProvider, sdkManager, new ContentCache());
+ builder.defaultOptions = options;
+ return builder;
+ }
+
+ @override
void moveContext(Folder from, Folder to) {
String path = from.path;
String path2 = to.path;
diff --git a/pkg/analysis_server/test/domain_analysis_test.dart b/pkg/analysis_server/test/domain_analysis_test.dart
index 45ca634..1a7671e 100644
--- a/pkg/analysis_server/test/domain_analysis_test.dart
+++ b/pkg/analysis_server/test/domain_analysis_test.dart
@@ -41,6 +41,7 @@
ExtensionManager manager = new ExtensionManager();
ServerPlugin serverPlugin = new ServerPlugin();
manager.processPlugins([serverPlugin]);
+ MockSdk sdk = new MockSdk(resourceProvider: resourceProvider);
server = new AnalysisServer(
serverChannel,
resourceProvider,
@@ -48,7 +49,7 @@
null,
serverPlugin,
new AnalysisServerOptions(),
- new DartSdkManager('', false, (_) => new MockSdk()),
+ new DartSdkManager('/', false, (_) => sdk),
InstrumentationService.NULL_SERVICE);
handler = new AnalysisDomainHandler(server);
});
@@ -250,7 +251,9 @@
return helper.onAnalysisComplete.then((_) {
Request request = new Request('0', ANALYSIS_UPDATE_CONTENT, {
'files': {
- helper.testFile: {TYPE: 'foo',}
+ helper.testFile: {
+ TYPE: 'foo',
+ }
}
});
Response response = helper.handler.handleRequest(request);
@@ -425,9 +428,8 @@
library lib_a;
class A {}
''');
- packageMapProvider.packageMap['pkgA'] = [
- resourceProvider.getResource('/packages/pkgA')
- ];
+ resourceProvider.newFile(
+ '/project/.packages', 'pkgA:file:///packages/pkgA');
addTestFile('''
import 'package:pkgA/libA.dart';
main(A a) {
@@ -468,6 +470,7 @@
ExtensionManager manager = new ExtensionManager();
ServerPlugin serverPlugin = new ServerPlugin();
manager.processPlugins([serverPlugin]);
+ MockSdk sdk = new MockSdk(resourceProvider: resourceProvider);
server = new AnalysisServer(
serverChannel,
resourceProvider,
@@ -475,7 +478,7 @@
null,
serverPlugin,
new AnalysisServerOptions(),
- new DartSdkManager('', false, (_) => new MockSdk()),
+ new DartSdkManager('/', false, (_) => sdk),
InstrumentationService.NULL_SERVICE);
handler = new AnalysisDomainHandler(server);
// listen for notifications
@@ -704,9 +707,8 @@
library lib_a;
class A {}
''');
- packageMapProvider.packageMap = {
- 'pkgA': [(resourceProvider.newFolder('/packages/pkgA/lib'))]
- };
+ resourceProvider.newFile(
+ '/project/.packages', 'pkgA:file:///packages/pkgA/lib');
//
addTestFile('''
import 'package:pkgA/libA.dart';
@@ -774,9 +776,7 @@
library lib_a;
class A {}
''');
- packageMapProvider.packageMap = {
- 'pkgA': [(resourceProvider.newFolder('/packages/pkgA/lib'))]
- };
+ resourceProvider.newFile('/project/.packages', 'pkgA:/packages/pkgA/lib');
//
addTestFile('// no "pkgA" reference');
createProject();
diff --git a/pkg/analysis_server/test/domain_diagnostic_test.dart b/pkg/analysis_server/test/domain_diagnostic_test.dart
index 3a6f3cb..1c4ba4a 100644
--- a/pkg/analysis_server/test/domain_diagnostic_test.dart
+++ b/pkg/analysis_server/test/domain_diagnostic_test.dart
@@ -47,6 +47,7 @@
//
var serverChannel = new MockServerChannel();
resourceProvider = new MemoryResourceProvider();
+ MockSdk sdk = new MockSdk(resourceProvider: resourceProvider);
server = new AnalysisServer(
serverChannel,
resourceProvider,
@@ -54,7 +55,7 @@
null,
serverPlugin,
new AnalysisServerOptions(),
- new DartSdkManager('', false, (_) => new MockSdk()),
+ new DartSdkManager('/', false, (_) => sdk),
InstrumentationService.NULL_SERVICE);
handler = new DiagnosticDomainHandler(server);
});
diff --git a/pkg/analysis_server/test/integration/analysis/get_errors_nonStandard_sdk.dart b/pkg/analysis_server/test/integration/analysis/get_errors_nonStandard_sdk.dart
index 2fee03a..70bd7aa 100644
--- a/pkg/analysis_server/test/integration/analysis/get_errors_nonStandard_sdk.dart
+++ b/pkg/analysis_server/test/integration/analysis/get_errors_nonStandard_sdk.dart
@@ -8,8 +8,6 @@
import 'dart:io';
import 'package:analysis_server/plugin/protocol/protocol.dart';
-import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:path/path.dart' as path;
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -75,10 +73,14 @@
}
@override
- Future startServer({int servicesPort, bool checked: true}) {
+ Future startServer(
+ {bool checked: true, int diagnosticPort, int servicesPort}) {
String sdkPath = createNonStandardSdk();
return server.start(
- servicesPort: servicesPort, checked: checked, sdkPath: sdkPath);
+ checked: checked,
+ diagnosticPort: diagnosticPort,
+ sdkPath: sdkPath,
+ servicesPort: servicesPort);
}
Future test_getErrors() async {
diff --git a/pkg/analysis_server/test/integration/analysis/highlights_test2.dart b/pkg/analysis_server/test/integration/analysis/highlights_test2.dart
index bd07449..c8d75ee 100644
--- a/pkg/analysis_server/test/integration/analysis/highlights_test2.dart
+++ b/pkg/analysis_server/test/integration/analysis/highlights_test2.dart
@@ -20,10 +20,12 @@
@reflectiveTest
class AnalysisHighlightsTest extends AbstractAnalysisServerIntegrationTest {
- Future startServer({int servicesPort, bool checked: true}) {
+ Future startServer(
+ {bool checked: true, int diagnosticPort, int servicesPort}) {
return server.start(
- servicesPort: servicesPort,
checked: checked,
+ diagnosticPort: diagnosticPort,
+ servicesPort: servicesPort,
useAnalysisHighlight2: true);
}
@@ -109,6 +111,7 @@
expect(highlights[type], equals(expected.toSet()));
highlights.remove(type);
}
+
check(HighlightRegionType.ANNOTATION, ['@override']);
check(HighlightRegionType.BUILT_IN,
['as', 'get', 'import', 'set', 'static', 'typedef']);
diff --git a/pkg/analysis_server/test/integration/integration_tests.dart b/pkg/analysis_server/test/integration/integration_tests.dart
index 5ae41f9..1893c18 100644
--- a/pkg/analysis_server/test/integration/integration_tests.dart
+++ b/pkg/analysis_server/test/integration/integration_tests.dart
@@ -205,8 +205,12 @@
/**
* Start [server].
*/
- Future startServer({int servicesPort, bool checked: true}) =>
- server.start(servicesPort: servicesPort, checked: checked);
+ Future startServer(
+ {bool checked: true, int diagnosticPort, int servicesPort}) =>
+ server.start(
+ checked: checked,
+ diagnosticPort: diagnosticPort,
+ servicesPort: servicesPort);
/**
* After every test, the server is stopped and [sourceDirectory] is deleted.
diff --git a/pkg/analysis_server/test/mock_sdk.dart b/pkg/analysis_server/test/mock_sdk.dart
index 5681817..0d39a19 100644
--- a/pkg/analysis_server/test/mock_sdk.dart
+++ b/pkg/analysis_server/test/mock_sdk.dart
@@ -242,18 +242,32 @@
LIB_INTERNAL,
];
- final resource.MemoryResourceProvider provider =
- new resource.MemoryResourceProvider();
+ static const String librariesContent = r'''
+const Map<String, LibraryInfo> libraries = const {
+ "async": const LibraryInfo("async/async.dart"),
+ "collection": const LibraryInfo("collection/collection.dart"),
+ "convert": const LibraryInfo("convert/convert.dart"),
+ "core": const LibraryInfo("core/core.dart"),
+ "html": const LibraryInfo("html/dartium/html_dartium.dart"),
+ "math": const LibraryInfo("math/math.dart"),
+ "_internal": const LibraryInfo("internal/internal.dart"),
+};
+''';
+
+ final resource.MemoryResourceProvider provider;
/**
* The [AnalysisContext] which is used for all of the sources.
*/
InternalAnalysisContext _analysisContext;
- MockSdk() {
+ MockSdk({resource.ResourceProvider resourceProvider})
+ : provider = resourceProvider ?? new resource.MemoryResourceProvider() {
LIBRARIES.forEach((SdkLibrary library) {
provider.newFile(library.path, (library as MockSdkLibrary).content);
});
+ provider.newFile('/lib/_internal/sdk_library_metadata/lib/libraries.dart',
+ librariesContent);
}
@override
diff --git a/pkg/analysis_server/test/search/type_hierarchy_test.dart b/pkg/analysis_server/test/search/type_hierarchy_test.dart
index 0dfc892..c3efbbf 100644
--- a/pkg/analysis_server/test/search/type_hierarchy_test.dart
+++ b/pkg/analysis_server/test/search/type_hierarchy_test.dart
@@ -33,7 +33,9 @@
void setUp() {
super.setUp();
createProject();
- server.handlers = [new SearchDomainHandler(server),];
+ server.handlers = [
+ new SearchDomainHandler(server),
+ ];
}
test_bad_function() async {
@@ -168,7 +170,7 @@
test_class_extends_fileAndPackageUris() async {
// prepare packages
- String pkgFile = '/packages/pkgA/libA.dart';
+ String pkgFile = '/packages/pkgA/lib/libA.dart';
resourceProvider.newFile(
pkgFile,
'''
@@ -176,14 +178,16 @@
class A {}
class B extends A {}
''');
- packageMapProvider.packageMap['pkgA'] = [
- resourceProvider.getResource('/packages/pkgA')
- ];
+ resourceProvider.newFile(
+ '/packages/pkgA/.packages', 'pkgA:file:///packages/pkgA/lib');
// reference the package from a project
+ resourceProvider.newFile(
+ '$projectPath/.packages', 'pkgA:file:///packages/pkgA/lib');
addTestFile('''
import 'package:pkgA/libA.dart';
class C extends A {}
''');
+ await waitForTasksFinished();
// configure roots
Request request =
new AnalysisSetAnalysisRootsParams([projectPath, '/packages/pkgA'], [])
diff --git a/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart b/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart
index bb4318b..f10a11d 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart
@@ -132,6 +132,39 @@
''');
}
+ test_createChange_add_toSynthetic() {
+ indexTestUnit('''
+class A {
+}
+class B extends A {
+ B() : super() {}
+ factory B._() = A;
+}
+main() {
+ new A();
+}
+''');
+ // configure refactoring
+ _createConstructorInvocationRefactoring('new A();');
+ expect(refactoring.refactoringName, 'Rename Constructor');
+ expect(refactoring.elementKindName, 'constructor');
+ expect(refactoring.oldName, '');
+ // validate change
+ refactoring.newName = 'newName';
+ return assertSuccessfulRefactoring('''
+class A {
+ A.newName();
+}
+class B extends A {
+ B() : super.newName() {}
+ factory B._() = A.newName;
+}
+main() {
+ new A.newName();
+}
+''');
+ }
+
test_createChange_change() {
indexTestUnit('''
class A {
@@ -210,4 +243,10 @@
search, (node) => node is ConstructorDeclaration);
createRenameRefactoringForElement(element);
}
+
+ void _createConstructorInvocationRefactoring(String search) {
+ ConstructorElement element = findNodeElementAtString(
+ search, (node) => node is InstanceCreationExpression);
+ createRenameRefactoringForElement(element);
+ }
}
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index 7aa782a..93ddb20 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -422,7 +422,7 @@
<field name="sources">
<map>
<key><ref>String</ref></key>
- <value><list>><ref>String</ref></list></value>
+ <value><list><ref>String</ref></list></value>
</map>
<p>
A mapping from source URIs to directly reachable source URIs. For example,
diff --git a/pkg/analyzer/doc/tasks.html b/pkg/analyzer/doc/tasks.html
index 3129e1a..df31e7a 100644
--- a/pkg/analyzer/doc/tasks.html
+++ b/pkg/analyzer/doc/tasks.html
@@ -53,24 +53,23 @@
CREATED_RESOLVED_UNIT [shape=box]
CREATED_RESOLVED_UNIT1 [shape=box]
CREATED_RESOLVED_UNIT10 -> InferInstanceMembersInUnitTask
+ CREATED_RESOLVED_UNIT10 -> InferStaticVariableTypeTask
+ CREATED_RESOLVED_UNIT10 -> PartiallyResolveUnitReferencesTask
+ CREATED_RESOLVED_UNIT10 -> ResolveInstanceFieldsInUnitTask
+ CREATED_RESOLVED_UNIT10 -> ResolveUnitTask
CREATED_RESOLVED_UNIT10 [shape=box]
- CREATED_RESOLVED_UNIT11 -> InferInstanceMembersInUnitTask
- CREATED_RESOLVED_UNIT11 -> InferStaticVariableTypeTask
- CREATED_RESOLVED_UNIT11 -> PartiallyResolveUnitReferencesTask
- CREATED_RESOLVED_UNIT11 -> ResolveInstanceFieldsInUnitTask
- CREATED_RESOLVED_UNIT11 -> ResolveUnitTask
+ CREATED_RESOLVED_UNIT11 -> ResolveConstantExpressionTask
CREATED_RESOLVED_UNIT11 [shape=box]
- CREATED_RESOLVED_UNIT12 -> ResolveConstantExpressionTask
CREATED_RESOLVED_UNIT12 [shape=box]
- CREATED_RESOLVED_UNIT13 [shape=box]
CREATED_RESOLVED_UNIT2 [shape=box]
CREATED_RESOLVED_UNIT3 [shape=box]
CREATED_RESOLVED_UNIT4 [shape=box]
CREATED_RESOLVED_UNIT5 [shape=box]
CREATED_RESOLVED_UNIT6 [shape=box]
CREATED_RESOLVED_UNIT7 [shape=box]
+ CREATED_RESOLVED_UNIT8 -> ResolveInstanceFieldsInUnitTask
CREATED_RESOLVED_UNIT8 [shape=box]
- CREATED_RESOLVED_UNIT9 -> ResolveInstanceFieldsInUnitTask
+ CREATED_RESOLVED_UNIT9 -> InferInstanceMembersInUnitTask
CREATED_RESOLVED_UNIT9 [shape=box]
ComputeConstantDependenciesTask -> CONSTANT_DEPENDENCIES
ComputeConstantValueTask -> CONSTANT_VALUE
@@ -78,7 +77,6 @@
ComputeLibraryCycleTask -> LIBRARY_CYCLE
ComputeLibraryCycleTask -> LIBRARY_CYCLE_DEPENDENCIES
ComputeLibraryCycleTask -> LIBRARY_CYCLE_UNITS
- ComputePropagableVariableDependenciesTask -> PROPAGABLE_VARIABLE_DEPENDENCIES
ComputeRequiredConstantsTask -> PENDING_ERRORS
ComputeRequiredConstantsTask -> REQUIRED_CONSTANTS
ContainingLibrariesTask -> CONTAINING_LIBRARIES
@@ -91,14 +89,14 @@
EXPORTED_LIBRARIES -> BuildDirectiveElementsTask
EXPORTED_LIBRARIES -> ReadyLibraryElement2Task
EXPORTED_LIBRARIES -> ReadyLibraryElement5Task
- EXPORTED_LIBRARIES -> ReadyLibraryElement6Task
+ EXPORTED_LIBRARIES -> ReadyLibraryElement7Task
EXPORTED_LIBRARIES -> ResolveTopLevelLibraryTypeBoundsTask
EXPORTED_LIBRARIES [shape=box]
EXPORT_SOURCE_CLOSURE -> BuildExportNamespaceTask
EXPORT_SOURCE_CLOSURE -> ResolveTopLevelUnitTypeBoundsTask
EXPORT_SOURCE_CLOSURE [shape=box]
- EvaluateUnitConstantsTask -> CREATED_RESOLVED_UNIT13
- EvaluateUnitConstantsTask -> RESOLVED_UNIT13
+ EvaluateUnitConstantsTask -> CREATED_RESOLVED_UNIT12
+ EvaluateUnitConstantsTask -> RESOLVED_UNIT12
GatherUsedImportedElementsTask -> USED_IMPORTED_ELEMENTS
GatherUsedLocalElementsTask -> USED_LOCAL_ELEMENTS
GenerateHintsTask -> HINTS
@@ -110,7 +108,7 @@
IMPORTED_LIBRARIES -> BuildDirectiveElementsTask
IMPORTED_LIBRARIES -> ReadyLibraryElement2Task
IMPORTED_LIBRARIES -> ReadyLibraryElement5Task
- IMPORTED_LIBRARIES -> ReadyLibraryElement6Task
+ IMPORTED_LIBRARIES -> ReadyLibraryElement7Task
IMPORTED_LIBRARIES -> ResolveTopLevelLibraryTypeBoundsTask
IMPORTED_LIBRARIES -> ResolveTopLevelUnitTypeBoundsTask
IMPORTED_LIBRARIES [shape=box]
@@ -124,12 +122,12 @@
INFERRED_STATIC_VARIABLE -> InferStaticVariableTypesInUnitTask
INFERRED_STATIC_VARIABLE [shape=box]
IS_LAUNCHABLE [shape=box]
- InferInstanceMembersInUnitTask -> CREATED_RESOLVED_UNIT11
- InferInstanceMembersInUnitTask -> RESOLVED_UNIT11
+ InferInstanceMembersInUnitTask -> CREATED_RESOLVED_UNIT10
+ InferInstanceMembersInUnitTask -> RESOLVED_UNIT10
InferStaticVariableTypeTask -> INFERRED_STATIC_VARIABLE
InferStaticVariableTypeTask -> STATIC_VARIABLE_RESOLUTION_ERRORS
- InferStaticVariableTypesInUnitTask -> CREATED_RESOLVED_UNIT9
- InferStaticVariableTypesInUnitTask -> RESOLVED_UNIT9
+ InferStaticVariableTypesInUnitTask -> CREATED_RESOLVED_UNIT8
+ InferStaticVariableTypesInUnitTask -> RESOLVED_UNIT8
InferStaticVariableTypesInUnitTask -> STATIC_VARIABLE_RESOLUTION_ERRORS_IN_UNIT
LIBRARY_CYCLE [shape=box]
LIBRARY_CYCLE_DEPENDENCIES -> InferInstanceMembersInUnitTask
@@ -163,12 +161,12 @@
LIBRARY_ELEMENT5 -> ResolveUnitTypeNamesTask
LIBRARY_ELEMENT5 [shape=box]
LIBRARY_ELEMENT6 -> PartiallyResolveUnitReferencesTask
- LIBRARY_ELEMENT6 -> PropagateVariableTypesInLibraryTask
LIBRARY_ELEMENT6 -> ReadyLibraryElement5Task
LIBRARY_ELEMENT6 -> ResolveInstanceFieldsInUnitTask
+ LIBRARY_ELEMENT6 -> ResolvedUnit7InLibraryTask
LIBRARY_ELEMENT6 [shape=box]
- LIBRARY_ELEMENT7 -> PropagateVariableTypesInLibraryClosureTask
- LIBRARY_ELEMENT7 -> ReadyLibraryElement6Task
+ LIBRARY_ELEMENT7 -> ReadyLibraryElement7Task
+ LIBRARY_ELEMENT7 -> ResolvedUnit7InLibraryClosureTask
LIBRARY_ELEMENT7 [shape=box]
LIBRARY_ELEMENT8 -> ResolveLibraryReferencesTask
LIBRARY_ELEMENT8 -> ResolveUnitTask
@@ -178,11 +176,11 @@
LIBRARY_ELEMENT9 [shape=box]
LIBRARY_ERRORS_READY [shape=box]
LIBRARY_SPECIFIC_UNITS -> GenerateHintsTask
- LIBRARY_SPECIFIC_UNITS -> PropagateVariableTypesInLibraryTask
LIBRARY_SPECIFIC_UNITS -> ReadyResolvedUnitTask
LIBRARY_SPECIFIC_UNITS -> ResolveLibraryReferencesTask
LIBRARY_SPECIFIC_UNITS -> ResolveLibraryTypeNamesTask
LIBRARY_SPECIFIC_UNITS -> ResolveTopLevelLibraryTypeBoundsTask
+ LIBRARY_SPECIFIC_UNITS -> ResolvedUnit7InLibraryTask
LIBRARY_SPECIFIC_UNITS [shape=box]
LIBRARY_UNIT_ERRORS -> dartErrorsForUnit
LIBRARY_UNIT_ERRORS [shape=box]
@@ -205,13 +203,6 @@
PARSE_ERRORS [shape=box]
PENDING_ERRORS -> VerifyUnitTask
PENDING_ERRORS [shape=box]
- PROPAGABLE_VARIABLES_IN_UNIT -> PropagateVariableTypesInUnitTask
- PROPAGABLE_VARIABLES_IN_UNIT [shape=box]
- PROPAGABLE_VARIABLE_DEPENDENCIES -> PropagateVariableTypeTask
- PROPAGABLE_VARIABLE_DEPENDENCIES [shape=box]
- PROPAGATED_VARIABLE -> PropagateVariableTypeTask
- PROPAGATED_VARIABLE -> PropagateVariableTypesInUnitTask
- PROPAGATED_VARIABLE [shape=box]
ParseDartTask -> EXPLICITLY_IMPORTED_LIBRARIES
ParseDartTask -> EXPORTED_LIBRARIES
ParseDartTask -> IMPORTED_LIBRARIES
@@ -225,21 +216,15 @@
ParseDartTask -> UNITS
PartiallyResolveUnitReferencesTask -> CREATED_RESOLVED_UNIT7
PartiallyResolveUnitReferencesTask -> INFERABLE_STATIC_VARIABLES_IN_UNIT
- PartiallyResolveUnitReferencesTask -> PROPAGABLE_VARIABLES_IN_UNIT
PartiallyResolveUnitReferencesTask -> RESOLVED_UNIT7
- PropagateVariableTypeTask -> PROPAGATED_VARIABLE
- PropagateVariableTypesInLibraryClosureTask -> LIBRARY_ELEMENT8
- PropagateVariableTypesInLibraryTask -> LIBRARY_ELEMENT7
- PropagateVariableTypesInUnitTask -> CREATED_RESOLVED_UNIT8
- PropagateVariableTypesInUnitTask -> RESOLVED_UNIT8
READY_LIBRARY_ELEMENT2 -> ComputeLibraryCycleTask
READY_LIBRARY_ELEMENT2 -> ReadyLibraryElement2Task
READY_LIBRARY_ELEMENT2 [shape=box]
READY_LIBRARY_ELEMENT6 -> PartiallyResolveUnitReferencesTask
READY_LIBRARY_ELEMENT6 -> ReadyLibraryElement5Task
READY_LIBRARY_ELEMENT6 [shape=box]
- READY_LIBRARY_ELEMENT7 -> PropagateVariableTypesInLibraryClosureTask
- READY_LIBRARY_ELEMENT7 -> ReadyLibraryElement6Task
+ READY_LIBRARY_ELEMENT7 -> ReadyLibraryElement7Task
+ READY_LIBRARY_ELEMENT7 -> ResolvedUnit7InLibraryClosureTask
READY_LIBRARY_ELEMENT7 [shape=box]
READY_RESOLVED_UNIT -> ResolveLibraryTask
READY_RESOLVED_UNIT -> VerifyUnitTask
@@ -260,17 +245,15 @@
RESOLVED_UNIT1 -> BuildLibraryElementTask
RESOLVED_UNIT1 -> ResolveDirectiveElementsTask
RESOLVED_UNIT1 [shape=box]
- RESOLVED_UNIT10 -> InferInstanceMembersInUnitTask
+ RESOLVED_UNIT10 -> ResolveUnitTask
RESOLVED_UNIT10 [shape=box]
- RESOLVED_UNIT11 -> ResolveUnitTask
+ RESOLVED_UNIT11 -> EvaluateUnitConstantsTask
+ RESOLVED_UNIT11 -> GatherUsedImportedElementsTask
+ RESOLVED_UNIT11 -> GatherUsedLocalElementsTask
+ RESOLVED_UNIT11 -> ResolveLibraryReferencesTask
RESOLVED_UNIT11 [shape=box]
- RESOLVED_UNIT12 -> EvaluateUnitConstantsTask
- RESOLVED_UNIT12 -> GatherUsedImportedElementsTask
- RESOLVED_UNIT12 -> GatherUsedLocalElementsTask
- RESOLVED_UNIT12 -> ResolveLibraryReferencesTask
+ RESOLVED_UNIT12 -> StrongModeVerifyUnitTask
RESOLVED_UNIT12 [shape=box]
- RESOLVED_UNIT13 -> StrongModeVerifyUnitTask
- RESOLVED_UNIT13 [shape=box]
RESOLVED_UNIT2 -> BuildEnumMemberElementsTask
RESOLVED_UNIT2 [shape=box]
RESOLVED_UNIT3 -> ResolveTopLevelUnitTypeBoundsTask
@@ -284,15 +267,13 @@
RESOLVED_UNIT6 -> PartiallyResolveUnitReferencesTask
RESOLVED_UNIT6 [shape=box]
RESOLVED_UNIT7 -> ComputeInferableStaticVariableDependenciesTask
- RESOLVED_UNIT7 -> ComputePropagableVariableDependenciesTask
- RESOLVED_UNIT7 -> PropagateVariableTypeTask
- RESOLVED_UNIT7 -> PropagateVariableTypesInUnitTask
+ RESOLVED_UNIT7 -> InferStaticVariableTypeTask
+ RESOLVED_UNIT7 -> InferStaticVariableTypesInUnitTask
+ RESOLVED_UNIT7 -> ResolvedUnit7InLibraryTask
RESOLVED_UNIT7 [shape=box]
- RESOLVED_UNIT8 -> InferStaticVariableTypeTask
- RESOLVED_UNIT8 -> InferStaticVariableTypesInUnitTask
- RESOLVED_UNIT8 -> PropagateVariableTypesInLibraryTask
+ RESOLVED_UNIT8 -> ResolveInstanceFieldsInUnitTask
RESOLVED_UNIT8 [shape=box]
- RESOLVED_UNIT9 -> ResolveInstanceFieldsInUnitTask
+ RESOLVED_UNIT9 -> InferInstanceMembersInUnitTask
RESOLVED_UNIT9 [shape=box]
RESOLVE_TYPE_BOUNDS_ERRORS -> LibraryUnitErrorsTask
RESOLVE_TYPE_BOUNDS_ERRORS [shape=box]
@@ -302,13 +283,13 @@
RESOLVE_UNIT_ERRORS [shape=box]
ReadyLibraryElement2Task -> READY_LIBRARY_ELEMENT2
ReadyLibraryElement5Task -> READY_LIBRARY_ELEMENT6
- ReadyLibraryElement6Task -> READY_LIBRARY_ELEMENT7
+ ReadyLibraryElement7Task -> READY_LIBRARY_ELEMENT7
ReadyResolvedUnitTask -> READY_RESOLVED_UNIT
ResolveConstantExpressionTask -> CONSTANT_EXPRESSION_RESOLVED
ResolveDirectiveElementsTask -> CREATED_RESOLVED_UNIT2
ResolveDirectiveElementsTask -> RESOLVED_UNIT2
- ResolveInstanceFieldsInUnitTask -> CREATED_RESOLVED_UNIT10
- ResolveInstanceFieldsInUnitTask -> RESOLVED_UNIT10
+ ResolveInstanceFieldsInUnitTask -> CREATED_RESOLVED_UNIT9
+ ResolveInstanceFieldsInUnitTask -> RESOLVED_UNIT9
ResolveLibraryReferencesTask -> LIBRARY_ELEMENT9
ResolveLibraryTask -> LIBRARY_ELEMENT
ResolveLibraryTypeNamesTask -> LIBRARY_ELEMENT6
@@ -317,8 +298,8 @@
ResolveTopLevelUnitTypeBoundsTask -> RESOLVED_UNIT4
ResolveTopLevelUnitTypeBoundsTask -> RESOLVE_TYPE_BOUNDS_ERRORS
ResolveUnitTask -> CONSTANT_EXPRESSIONS_DEPENDENCIES
- ResolveUnitTask -> CREATED_RESOLVED_UNIT12
- ResolveUnitTask -> RESOLVED_UNIT12
+ ResolveUnitTask -> CREATED_RESOLVED_UNIT11
+ ResolveUnitTask -> RESOLVED_UNIT11
ResolveUnitTask -> RESOLVE_UNIT_ERRORS
ResolveUnitTypeNamesTask -> CREATED_RESOLVED_UNIT5
ResolveUnitTypeNamesTask -> RESOLVED_UNIT5
@@ -326,6 +307,8 @@
ResolveVariableReferencesTask -> CREATED_RESOLVED_UNIT6
ResolveVariableReferencesTask -> RESOLVED_UNIT6
ResolveVariableReferencesTask -> VARIABLE_REFERENCE_ERRORS
+ ResolvedUnit7InLibraryClosureTask -> LIBRARY_ELEMENT8
+ ResolvedUnit7InLibraryTask -> LIBRARY_ELEMENT7
SCAN_ERRORS -> dartErrorsForSource
SCAN_ERRORS [shape=box]
SOURCE_KIND -> BuildDirectiveElementsTask
@@ -352,7 +335,6 @@
TYPE_PROVIDER -> InferInstanceMembersInUnitTask
TYPE_PROVIDER -> InferStaticVariableTypeTask
TYPE_PROVIDER -> PartiallyResolveUnitReferencesTask
- TYPE_PROVIDER -> PropagateVariableTypeTask
TYPE_PROVIDER -> ResolveInstanceFieldsInUnitTask
TYPE_PROVIDER -> ResolveLibraryTypeNamesTask
TYPE_PROVIDER -> ResolveTopLevelUnitTypeBoundsTask
diff --git a/pkg/analyzer/lib/file_system/file_system.dart b/pkg/analyzer/lib/file_system/file_system.dart
index 8fb6025..f005eef 100644
--- a/pkg/analyzer/lib/file_system/file_system.dart
+++ b/pkg/analyzer/lib/file_system/file_system.dart
@@ -54,12 +54,6 @@
File renameSync(String newPath);
/**
- * Return a file that refers to the same file as this file, but whose path
- * does not contain any symbolic links.
- */
- File resolveSymbolicLinksSync();
-
- /**
* Synchronously write the given [bytes] to the file. The new content will
* replace any existing content.
*
@@ -183,6 +177,12 @@
bool isOrContains(String path);
/**
+ * Return a resource that refers to the same resource as this resource, but
+ * whose path does not contain any symbolic links.
+ */
+ Resource resolveSymbolicLinksSync();
+
+ /**
* Return a Uri representing this resource.
*/
Uri toUri();
diff --git a/pkg/analyzer/lib/file_system/memory_file_system.dart b/pkg/analyzer/lib/file_system/memory_file_system.dart
index d179d7f..0ba9b94 100644
--- a/pkg/analyzer/lib/file_system/memory_file_system.dart
+++ b/pkg/analyzer/lib/file_system/memory_file_system.dart
@@ -201,6 +201,15 @@
return file;
}
+ /**
+ * Write a representation of the file system on the given [sink].
+ */
+ void writeOn(StringSink sink) {
+ List<String> paths = _pathToResource.keys.toList();
+ paths.sort();
+ paths.forEach(sink.writeln);
+ }
+
void _checkFileAtPath(String path) {
_MemoryResource resource = _pathToResource[path];
if (resource is! _MemoryFile) {
@@ -484,6 +493,9 @@
}
@override
+ Folder resolveSymbolicLinksSync() => this;
+
+ @override
Uri toUri() =>
new Uri.directory(path, windows: _provider.pathContext == windows);
}
diff --git a/pkg/analyzer/lib/file_system/physical_file_system.dart b/pkg/analyzer/lib/file_system/physical_file_system.dart
index b771149..38fc38a 100644
--- a/pkg/analyzer/lib/file_system/physical_file_system.dart
+++ b/pkg/analyzer/lib/file_system/physical_file_system.dart
@@ -217,6 +217,11 @@
@override
Stream<WatchEvent> get changes => new DirectoryWatcher(_entry.path).events;
+ /**
+ * Return the underlying file being represented by this wrapper.
+ */
+ io.Directory get _directory => _entry as io.Directory;
+
@override
String canonicalizePath(String relPath) {
return normalize(join(path, relPath));
@@ -277,6 +282,16 @@
}
@override
+ Folder resolveSymbolicLinksSync() {
+ try {
+ return new _PhysicalFolder(
+ new io.Directory(_directory.resolveSymbolicLinksSync()));
+ } on io.FileSystemException catch (exception) {
+ throw new FileSystemException(exception.path, exception.message);
+ }
+ }
+
+ @override
Uri toUri() => new Uri.directory(path);
}
diff --git a/pkg/analyzer/lib/src/context/builder.dart b/pkg/analyzer/lib/src/context/builder.dart
index 51c0a21..65928bf 100644
--- a/pkg/analyzer/lib/src/context/builder.dart
+++ b/pkg/analyzer/lib/src/context/builder.dart
@@ -9,6 +9,7 @@
import 'package:analyzer/context/declared_variables.dart';
import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/plugin/options.dart';
import 'package:analyzer/plugin/resolver_provider.dart';
import 'package:analyzer/source/analysis_options_provider.dart';
import 'package:analyzer/source/package_map_resolver.dart';
@@ -20,6 +21,7 @@
import 'package:package_config/packages.dart';
import 'package:package_config/packages_file.dart';
import 'package:package_config/src/packages_impl.dart';
+import 'package:path/src/context.dart';
import 'package:yaml/yaml.dart';
/**
@@ -121,11 +123,9 @@
* *Note:* This method is not yet fully implemented and should not be used.
*/
AnalysisContext buildContext(String path) {
- // TODO(brianwilkerson) Split getAnalysisOptions so we can capture the
- // option map and use it to run the options processors.
- AnalysisOptions options = getAnalysisOptions(path);
InternalAnalysisContext context =
AnalysisEngine.instance.createAnalysisContext();
+ AnalysisOptions options = getAnalysisOptions(context, path);
context.contentCache = contentCache;
context.sourceFactory = createSourceFactory(path, options);
context.analysisOptions = options;
@@ -184,6 +184,7 @@
File configFile = resourceProvider.getFile(defaultPackageFilePath);
List<int> bytes = configFile.readAsBytesSync();
Map<String, Uri> map = parse(bytes, configFile.toUri());
+ resolveSymbolicLinks(map);
return new MapPackages(map);
} else if (defaultPackagesDirectoryPath != null) {
Folder folder = resourceProvider.getFolder(defaultPackagesDirectoryPath);
@@ -215,7 +216,7 @@
packageResolver,
fileResolver
];
- return new SourceFactory(resolvers);
+ return new SourceFactory(resolvers, null, resourceProvider);
}
}
Packages packages = createPackageMap(rootDirectoryPath);
@@ -225,10 +226,12 @@
if (packageMap != null) {
// TODO(brianwilkerson) I think that we don't need a PackageUriResolver
// when we can pass the packages object to the source factory directly.
+ // Actually, I think we're using it to restoreUri, which could lead to
+ // inconsistencies.
resolvers.add(new PackageMapUriResolver(resourceProvider, packageMap));
}
resolvers.add(fileResolver);
- return new SourceFactory(resolvers);
+ return new SourceFactory(resolvers, packages, resourceProvider);
}
/**
@@ -260,6 +263,7 @@
List<int> fileBytes = location.readAsBytesSync();
Map<String, Uri> map =
parse(fileBytes, resourceProvider.pathContext.toUri(location.path));
+ resolveSymbolicLinks(map);
return new MapPackages(map);
} else if (location is Folder) {
return getPackagesFromFolder(location);
@@ -334,16 +338,24 @@
}
/**
- * Return the analysis options that should be used when analyzing code in the
- * directory with the given [path].
+ * Return the analysis options that should be used when the given [context] is
+ * used to analyze code in the directory with the given [path].
*/
- AnalysisOptions getAnalysisOptions(String path) {
+ AnalysisOptions getAnalysisOptions(AnalysisContext context, String path) {
AnalysisOptionsImpl options = createDefaultOptions();
File optionsFile = getOptionsFile(path);
if (optionsFile != null) {
- Map<String, YamlNode> fileOptions =
- new AnalysisOptionsProvider().getOptionsFromFile(optionsFile);
- applyToAnalysisOptions(options, fileOptions);
+ List<OptionsProcessor> optionsProcessors =
+ AnalysisEngine.instance.optionsPlugin.optionsProcessors;
+ try {
+ Map<String, YamlNode> optionMap =
+ new AnalysisOptionsProvider().getOptionsFromFile(optionsFile);
+ optionsProcessors.forEach(
+ (OptionsProcessor p) => p.optionsProcessed(context, optionMap));
+ applyToAnalysisOptions(options, optionMap);
+ } on Exception catch (exception) {
+ optionsProcessors.forEach((OptionsProcessor p) => p.onError(exception));
+ }
}
return options;
}
@@ -379,23 +391,49 @@
* directory.
*/
Packages getPackagesFromFolder(Folder folder) {
+ Context pathContext = resourceProvider.pathContext;
Map<String, Uri> map = new HashMap<String, Uri>();
for (Resource child in folder.getChildren()) {
if (child is Folder) {
- String packageName = resourceProvider.pathContext.basename(child.path);
- // Create a file URI (rather than a directory URI) and add a '.' so that
- // the URI is suitable for resolving relative URI's against it.
- //
- // TODO(brianwilkerson) Decide whether we need to pass in a 'windows:'
- // argument for testing purposes.
- map[packageName] = resourceProvider.pathContext.toUri(
- resourceProvider.pathContext.join(folder.path, packageName, '.'));
+ // Inline resolveSymbolicLinks for performance reasons.
+ String packageName = pathContext.basename(child.path);
+ String folderPath = resolveSymbolicLink(child);
+ String uriPath = pathContext.join(folderPath, '.');
+ map[packageName] = pathContext.toUri(uriPath);
}
}
return new MapPackages(map);
}
/**
+ * Resolve any symbolic links encoded in the path to the given [folder].
+ */
+ String resolveSymbolicLink(Folder folder) {
+ try {
+ return folder.resolveSymbolicLinksSync().path;
+ } on FileSystemException {
+ return folder.path;
+ }
+ }
+
+ /**
+ * Resolve any symbolic links encoded in the URI's in the given [map] by
+ * replacing the values in the map.
+ */
+ void resolveSymbolicLinks(Map<String, Uri> map) {
+ Context pathContext = resourceProvider.pathContext;
+ for (String packageName in map.keys) {
+ Folder folder =
+ resourceProvider.getFolder(pathContext.fromUri(map[packageName]));
+ String folderPath = resolveSymbolicLink(folder);
+ // Add a '.' so that the URI is suitable for resolving relative URI's
+ // against it.
+ String uriPath = pathContext.join(folderPath, '.');
+ map[packageName] = pathContext.toUri(uriPath);
+ }
+ }
+
+ /**
* Find the location of the package resolution file/directory for the
* directory at the given absolute [path].
*
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index 55cd2c8..6b15c8e 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.dart
@@ -284,6 +284,8 @@
(this._options.lint && !options.lint) ||
this._options.preserveComments != options.preserveComments ||
this._options.strongMode != options.strongMode ||
+ this._options.enableAssertInitializer !=
+ options.enableAssertInitializer ||
this._options.enableAssertMessage != options.enableAssertMessage ||
((options is AnalysisOptionsImpl)
? this._options.strongModeHints != options.strongModeHints
@@ -312,6 +314,7 @@
this._options.generateSdkErrors = options.generateSdkErrors;
this._options.dart2jsHint = options.dart2jsHint;
this._options.enableGenericMethods = options.enableGenericMethods;
+ this._options.enableAssertInitializer = options.enableAssertInitializer;
this._options.enableAssertMessage = options.enableAssertMessage;
this._options.enableStrictCallChecks = options.enableStrictCallChecks;
this._options.enableAsync = options.enableAsync;
@@ -1306,7 +1309,6 @@
entry.setState(RESOLVED_UNIT10, CacheState.FLUSHED);
entry.setState(RESOLVED_UNIT11, CacheState.FLUSHED);
entry.setState(RESOLVED_UNIT12, CacheState.FLUSHED);
- entry.setState(RESOLVED_UNIT13, CacheState.FLUSHED);
// USED_IMPORTED_ELEMENTS
// USED_LOCAL_ELEMENTS
setValue(STRONG_MODE_ERRORS, AnalysisError.NO_ERRORS);
@@ -1386,7 +1388,6 @@
entry.setState(RESOLVED_UNIT10, CacheState.FLUSHED);
entry.setState(RESOLVED_UNIT11, CacheState.FLUSHED);
entry.setState(RESOLVED_UNIT12, CacheState.FLUSHED);
- entry.setState(RESOLVED_UNIT13, CacheState.FLUSHED);
entry.setState(RESOLVED_UNIT, CacheState.FLUSHED);
}
@@ -1571,7 +1572,6 @@
new LibrarySpecificUnit(librarySource, unitSource);
for (ResultDescriptor result in [
RESOLVED_UNIT,
- RESOLVED_UNIT13,
RESOLVED_UNIT12,
RESOLVED_UNIT11,
RESOLVED_UNIT10,
diff --git a/pkg/analyzer/lib/src/dart/sdk/sdk.dart b/pkg/analyzer/lib/src/dart/sdk/sdk.dart
index ec64039..07e30c8 100644
--- a/pkg/analyzer/lib/src/dart/sdk/sdk.dart
+++ b/pkg/analyzer/lib/src/dart/sdk/sdk.dart
@@ -10,6 +10,7 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/dart/scanner/reader.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart';
@@ -614,9 +615,13 @@
lastStackTrace = stackTrace;
}
}
+ StringBuffer buffer = new StringBuffer();
+ buffer.writeln('Could not initialize the library map from $searchedPaths');
+ if (resourceProvider is MemoryResourceProvider) {
+ (resourceProvider as MemoryResourceProvider).writeOn(buffer);
+ }
AnalysisEngine.instance.logger.logError(
- "Could not initialize the library map from $searchedPaths",
- new CaughtException(lastException, lastStackTrace));
+ buffer.toString(), new CaughtException(lastException, lastStackTrace));
return new LibraryMap();
}
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index b229169..aa9a74b 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -1049,6 +1049,12 @@
bool get dart2jsHint;
/**
+ * Return `true` if the parser is to parse asserts in the initializer list of
+ * a constructor.
+ */
+ bool get enableAssertInitializer;
+
+ /**
* Return `true` to enable custom assert messages (DEP 37).
*/
bool get enableAssertMessage;
@@ -1202,100 +1208,61 @@
AnalyzeFunctionBodiesPredicate _analyzeFunctionBodiesPredicate =
_analyzeAllFunctionBodies;
- /**
- * The maximum number of sources for which AST structures should be kept in
- * the cache.
- */
+ @override
int cacheSize = DEFAULT_CACHE_SIZE;
- /**
- * A flag indicating whether analysis is to generate dart2js related hint
- * results.
- */
+ @override
bool dart2jsHint = false;
- /**
- * A flag indicating whether custom assert messages are to be supported (DEP
- * 37).
- */
+ @override
+ bool enableAssertInitializer = false;
+
+ @override
bool enableAssertMessage = false;
- /**
- * A flag indicating whether analysis is to enable async support.
- */
+ @override
bool enableAsync = true;
- /**
- * A flag indicating whether generic methods are to be supported (DEP 22).
- */
+ @override
bool enableGenericMethods = false;
@override
bool enableLazyAssignmentOperators = false;
- /**
- * A flag indicating whether analysis is to strictly follow the specification
- * when generating warnings on "call" methods (fixes dartbug.com/21938).
- */
+ @override
bool enableStrictCallChecks = false;
- /**
- * A flag indicating whether mixins are allowed to inherit from types other
- * than Object, and are allowed to reference `super`.
- */
+ @override
bool enableSuperMixins = false;
@override
bool enableTiming = false;
- /**
- * A flag indicating whether errors, warnings and hints should be generated
- * for sources that are implicitly being analyzed.
- */
+ @override
bool generateImplicitErrors = true;
- /**
- * A flag indicating whether errors, warnings and hints should be generated
- * for sources in the SDK.
- */
+ @override
bool generateSdkErrors = false;
- /**
- * A flag indicating whether analysis is to generate hint results (e.g. type
- * inference based information and pub best practices).
- */
+ @override
bool hint = true;
- /**
- * A flag indicating whether incremental analysis should be used.
- */
+ @override
bool incremental = false;
- /**
- * A flag indicating whether incremental analysis should be used for API
- * changes.
- */
+ @override
bool incrementalApi = false;
- /**
- * A flag indicating whether validation should be performed after incremental
- * analysis.
- */
+ @override
bool incrementalValidation = false;
- /**
- * A flag indicating whether analysis is to generate lint warnings.
- */
+ @override
bool lint = false;
- /**
- * A flag indicating whether analysis is to parse comments.
- */
+ @override
bool preserveComments = true;
- /**
- * A flag indicating whether strong-mode analysis should be used.
- */
+ @override
bool strongMode = false;
/**
@@ -1352,6 +1319,7 @@
analyzeFunctionBodiesPredicate = options.analyzeFunctionBodiesPredicate;
cacheSize = options.cacheSize;
dart2jsHint = options.dart2jsHint;
+ enableAssertInitializer = options.enableAssertInitializer;
enableAssertMessage = options.enableAssertMessage;
enableAsync = options.enableAsync;
enableStrictCallChecks = options.enableStrictCallChecks;
diff --git a/pkg/analyzer/lib/src/generated/incremental_resolver.dart b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
index c1bc461..9c6cbf8 100644
--- a/pkg/analyzer/lib/src/generated/incremental_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
@@ -98,11 +98,10 @@
isByTask(ComputeConstantValueTask.DESCRIPTOR) ||
isByTask(ComputeInferableStaticVariableDependenciesTask.DESCRIPTOR) ||
isByTask(ComputeLibraryCycleTask.DESCRIPTOR) ||
- isByTask(ComputePropagableVariableDependenciesTask.DESCRIPTOR) ||
isByTask(DartErrorsTask.DESCRIPTOR) ||
isByTask(ReadyLibraryElement2Task.DESCRIPTOR) ||
isByTask(ReadyLibraryElement5Task.DESCRIPTOR) ||
- isByTask(ReadyLibraryElement6Task.DESCRIPTOR) ||
+ isByTask(ReadyLibraryElement7Task.DESCRIPTOR) ||
isByTask(ReadyResolvedUnitTask.DESCRIPTOR) ||
isByTask(EvaluateUnitConstantsTask.DESCRIPTOR) ||
isByTask(GenerateHintsTask.DESCRIPTOR) ||
@@ -113,13 +112,11 @@
isByTask(LibraryUnitErrorsTask.DESCRIPTOR) ||
isByTask(ParseDartTask.DESCRIPTOR) ||
isByTask(PartiallyResolveUnitReferencesTask.DESCRIPTOR) ||
- isByTask(PropagateVariableTypesInLibraryClosureTask.DESCRIPTOR) ||
- isByTask(PropagateVariableTypesInLibraryTask.DESCRIPTOR) ||
- isByTask(PropagateVariableTypesInUnitTask.DESCRIPTOR) ||
- isByTask(PropagateVariableTypeTask.DESCRIPTOR) ||
isByTask(ScanDartTask.DESCRIPTOR) ||
isByTask(ResolveConstantExpressionTask.DESCRIPTOR) ||
isByTask(ResolveDirectiveElementsTask.DESCRIPTOR) ||
+ isByTask(ResolvedUnit7InLibraryClosureTask.DESCRIPTOR) ||
+ isByTask(ResolvedUnit7InLibraryTask.DESCRIPTOR) ||
isByTask(ResolveInstanceFieldsInUnitTask.DESCRIPTOR) ||
isByTask(ResolveLibraryReferencesTask.DESCRIPTOR) ||
isByTask(ResolveLibraryTask.DESCRIPTOR) ||
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index fcf9b01..d3f7475 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -2135,6 +2135,12 @@
int _errorListenerLock = 0;
/**
+ * A flag indicating whether the parser is to parse asserts in the initializer
+ * list of a constructor.
+ */
+ bool _enableAssertInitializer = false;
+
+ /**
* A flag indicating whether the parser is to parse the async support.
*/
bool _parseAsync = true;
@@ -2202,6 +2208,20 @@
}
/**
+ * Return `true` if the parser is to parse asserts in the initializer list of
+ * a constructor.
+ */
+ bool get enableAssertInitializer => _enableAssertInitializer;
+
+ /**
+ * Set whether the parser is to parse asserts in the initializer list of a
+ * constructor to match the given [enable] flag.
+ */
+ void set enableAssertInitializer(bool enable) {
+ _enableAssertInitializer = enable;
+ }
+
+ /**
* Return `true` if the current token is the first token of a return type that
* is followed by an identifier, possibly followed by a list of type
* parameters, followed by a left-parenthesis. This is used by
@@ -2862,6 +2882,7 @@
"parseDirective invoked in an invalid state (currentToken = $_currentToken)");
}
}
+
Directive directive = parseDirective();
if (declarations.length > 0 && !directiveFoundAfterDeclaration) {
_reportErrorForToken(ParserErrorCode.DIRECTIVE_AFTER_DECLARATION,
@@ -4346,6 +4367,31 @@
}
/**
+ * Parse an assert within a constructor's initializer list. Return the assert.
+ *
+ * This method assumes that the current token matches `Keyword.ASSERT`.
+ *
+ * assertInitializer ::=
+ * 'assert' '(' expression [',' expression] ')'
+ */
+ void _parseAssertInitializer() {
+ // TODO(brianwilkerson) Capture the syntax in the AST using a new class,
+ // such as AssertInitializer
+ Token keyword = getAndAdvance();
+ Token leftParen = _expect(TokenType.OPEN_PAREN);
+ Expression expression = parseExpression2();
+ Token comma;
+ Expression message;
+ if (_matches(TokenType.COMMA)) {
+ comma = getAndAdvance();
+ message = parseExpression2();
+ }
+ Token rightParen = _expect(TokenType.CLOSE_PAREN);
+// return new AssertInitializer(
+// keyword, leftParen, expression, comma, message, rightParen);
+ }
+
+ /**
* Parse an assert statement. Return the assert statement.
*
* This method assumes that the current token matches `Keyword.ASSERT`.
@@ -5502,6 +5548,9 @@
} else if (_matches(TokenType.OPEN_CURLY_BRACKET) ||
_matches(TokenType.FUNCTION)) {
_reportErrorForCurrentToken(ParserErrorCode.MISSING_INITIALIZER);
+ } else if (_enableAssertInitializer &&
+ _matchesKeyword(Keyword.ASSERT)) {
+ _parseAssertInitializer();
} else {
initializers.add(_parseConstructorFieldInitializer(false));
}
@@ -8282,6 +8331,7 @@
Keyword keyword = _currentToken.keyword;
return keyword == Keyword.CASE || keyword == Keyword.DEFAULT;
}
+
while (!atEndOrNextMember()) {
_advance();
}
@@ -8625,6 +8675,7 @@
type == TokenType.INT ||
type == TokenType.DOUBLE;
}
+
while ((_tokenMatchesIdentifier(token) && !isKeywordAfterUri(token)) ||
isValidInUri(token)) {
token = token.next;
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 9d04dff..e11afca 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -4963,7 +4963,11 @@
* inference.
*/
static void setType(AstNode node, DartType type) {
- node?.setProperty(_typeProperty, type);
+ if (type == null || type.isDynamic) {
+ clearType(node);
+ } else {
+ node?.setProperty(_typeProperty, type);
+ }
}
/**
@@ -5202,12 +5206,6 @@
final List<VariableElement> staticVariables = <VariableElement>[];
/**
- * The static and instance variables and fields that have an initializer.
- * These are the variables whose types might be propagated.
- */
- final List<VariableElement> propagableVariables = <VariableElement>[];
-
- /**
* Initialize a newly created visitor to resolve the nodes in an AST node.
*
* The [definingLibrary] is the element for the library containing the node
@@ -5248,7 +5246,6 @@
@override
Object visitFieldDeclaration(FieldDeclaration node) {
- _addPropagableVariables(node.fields.variables);
if (node.isStatic) {
_addStaticVariables(node.fields.variables);
}
@@ -5262,28 +5259,11 @@
@override
Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
- _addPropagableVariables(node.variables.variables);
_addStaticVariables(node.variables.variables);
return super.visitTopLevelVariableDeclaration(node);
}
/**
- * Add all of the [variables] with initializers to [propagableVariables].
- */
- void _addPropagableVariables(List<VariableDeclaration> variables) {
- int length = variables.length;
- for (int i = 0; i < length; i++) {
- VariableDeclaration variable = variables[i];
- if (variable.name.name.isNotEmpty && variable.initializer != null) {
- VariableElement element = variable.element;
- if (element.isConst || element.isFinal) {
- propagableVariables.add(element);
- }
- }
- }
- }
-
- /**
* Add all of the [variables] with initializers to the list of variables whose
* type can be inferred. Technically, we only infer the types of variables
* that do not have a static type, but all variables with initializers
@@ -6625,8 +6605,10 @@
//
// We can't represent this in Dart so we populate it here during
// inference.
- returnType = FutureUnionType.from(
- futureThenType.returnType, typeProvider, typeSystem);
+ var typeParamS =
+ futureThenType.returnType.flattenFutures(typeSystem);
+ returnType =
+ FutureUnionType.from(typeParamS, typeProvider, typeSystem);
} else {
returnType = _computeReturnOrYieldType(functionType.returnType);
}
@@ -7185,7 +7167,8 @@
return (typeArgs?.length == 1) ? typeArgs[0] : null;
}
// async functions expect `Future<T> | T`
- return new FutureUnionType(declaredType, typeProvider, typeSystem);
+ var futureTypeParam = declaredType.flattenFutures(typeSystem);
+ return FutureUnionType.from(futureTypeParam, typeProvider, typeSystem);
}
return declaredType;
}
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 1abf232..e7d747e 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -1426,17 +1426,9 @@
inferredTypes[i] =
variance.passedIn || bound.lower.isBottom ? bound.upper : bound.lower;
- // See if the constraints on the type variable are satisfied.
- //
- // If not, bail out of the analysis, unless a partial solution was
- // requested. If we are willing to accept a partial solution, fall back to
- // the known upper bound (if any) or `dynamic` for this unsolvable type
- // variable.
- if (inferredTypes[i].isBottom ||
- !isSubtypeOf(inferredTypes[i],
- bound.upper.substitute2(inferredTypes, fnTypeParams)) ||
- !isSubtypeOf(bound.lower.substitute2(inferredTypes, fnTypeParams),
- inferredTypes[i])) {
+ // See if the bounds can be satisfied.
+ if (bound.upper.isBottom ||
+ !_typeSystem.isSubtypeOf(bound.lower, bound.upper)) {
// Inference failed. Bail.
return null;
}
@@ -1607,21 +1599,14 @@
final List<DartType> _types;
/**
- * Creates a union of `Future< flatten(T) > | flatten(T)`.
+ * Creates a union of `Future<T> | T`.
*/
- factory FutureUnionType(
- DartType type, TypeProvider provider, TypeSystem system) {
- type = type.flattenFutures(system);
-
- // The order of these types is important: T could be a type variable, so
- // we want to try and match `Future<T>` before we try and match `T`.
- return new FutureUnionType._([
- provider.futureType.instantiate([type]),
- type
- ]);
- }
-
- FutureUnionType._(this._types) : super(null, null);
+ FutureUnionType._(DartType type, TypeProvider provider, TypeSystem system)
+ : _types = [
+ provider.futureType.instantiate([type]),
+ type
+ ],
+ super(null, null);
DartType get futureOfType => _types[0];
@@ -1676,15 +1661,39 @@
throw new UnsupportedError('Future unions are not used in typedefs');
/**
- * Creates a union of `flatten(T) | Future<flatten(T)>`, unless `T` is
- * already a future-union, in which case it simply returns `T`
+ * Creates a union of `T | Future<T>`, unless `T` is already a future or a
+ * future-union, in which case it simply returns `T`.
+ *
+ * Conceptually this is used as the inverse of the `flatten(T)` operation,
+ * defined as:
+ *
+ * - `flatten(Future<T>) -> T`
+ * - `flatten(T) -> T`
+ *
+ * Thus the inverse will give us `T | Future<T>`.
+ *
+ * If [type] is top (dynamic or Object) then the resulting union type is
+ * equivalent to top, so we simply return it.
+ *
+ * For a similar reason `Future<T> | Future<Future<T>>` is equivalent to just
+ * `Future<T>`, so we return it. Note that it is not possible to get a
+ * `Future<T>` as a result of `flatten`, so a this case likely indicates a
+ * type error in the code, but it will be reported elsewhere.
*/
static DartType from(
DartType type, TypeProvider provider, TypeSystem system) {
+ if (_isTop(type)) {
+ return type;
+ }
+ if (!identical(type, type.flattenFutures(system))) {
+ // As noted above, this most likely represents erroneous input.
+ return type;
+ }
+
if (type is FutureUnionType) {
return type;
}
- return new FutureUnionType(type, provider, system);
+ return new FutureUnionType._(type, provider, system);
}
}
diff --git a/pkg/analyzer/lib/src/plugin/engine_plugin.dart b/pkg/analyzer/lib/src/plugin/engine_plugin.dart
index 8e47707..ecf2e36 100644
--- a/pkg/analyzer/lib/src/plugin/engine_plugin.dart
+++ b/pkg/analyzer/lib/src/plugin/engine_plugin.dart
@@ -205,8 +205,6 @@
taskId, ComputeInferableStaticVariableDependenciesTask.DESCRIPTOR);
registerExtension(taskId, ComputeLibraryCycleTask.DESCRIPTOR);
registerExtension(taskId, ComputeRequiredConstantsTask.DESCRIPTOR);
- registerExtension(
- taskId, ComputePropagableVariableDependenciesTask.DESCRIPTOR);
registerExtension(taskId, ContainingLibrariesTask.DESCRIPTOR);
registerExtension(taskId, DartErrorsTask.DESCRIPTOR);
registerExtension(taskId, EvaluateUnitConstantsTask.DESCRIPTOR);
@@ -221,17 +219,14 @@
registerExtension(taskId, LibraryUnitErrorsTask.DESCRIPTOR);
registerExtension(taskId, ParseDartTask.DESCRIPTOR);
registerExtension(taskId, PartiallyResolveUnitReferencesTask.DESCRIPTOR);
- registerExtension(
- taskId, PropagateVariableTypesInLibraryClosureTask.DESCRIPTOR);
- registerExtension(taskId, PropagateVariableTypesInLibraryTask.DESCRIPTOR);
- registerExtension(taskId, PropagateVariableTypesInUnitTask.DESCRIPTOR);
- registerExtension(taskId, PropagateVariableTypeTask.DESCRIPTOR);
registerExtension(taskId, ReadyLibraryElement2Task.DESCRIPTOR);
registerExtension(taskId, ReadyLibraryElement5Task.DESCRIPTOR);
- registerExtension(taskId, ReadyLibraryElement6Task.DESCRIPTOR);
+ registerExtension(taskId, ReadyLibraryElement7Task.DESCRIPTOR);
registerExtension(taskId, ReadyResolvedUnitTask.DESCRIPTOR);
registerExtension(taskId, ResolveConstantExpressionTask.DESCRIPTOR);
registerExtension(taskId, ResolveDirectiveElementsTask.DESCRIPTOR);
+ registerExtension(taskId, ResolvedUnit7InLibraryClosureTask.DESCRIPTOR);
+ registerExtension(taskId, ResolvedUnit7InLibraryTask.DESCRIPTOR);
registerExtension(taskId, ResolveInstanceFieldsInUnitTask.DESCRIPTOR);
registerExtension(taskId, ResolveLibraryReferencesTask.DESCRIPTOR);
registerExtension(taskId, ResolveLibraryTask.DESCRIPTOR);
diff --git a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
index dc9685f..caa98d2 100644
--- a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
@@ -253,8 +253,7 @@
result == CREATED_RESOLVED_UNIT8 ||
result == CREATED_RESOLVED_UNIT9 ||
result == CREATED_RESOLVED_UNIT10 ||
- result == CREATED_RESOLVED_UNIT11 ||
- result == CREATED_RESOLVED_UNIT12) {
+ result == CREATED_RESOLVED_UNIT11) {
entry.setValue(result, true, TargetedResult.EMPTY_LIST);
return true;
}
@@ -269,7 +268,7 @@
}
}
} else if (target is VariableElement) {
- if (result == PROPAGATED_VARIABLE || result == INFERRED_STATIC_VARIABLE) {
+ if (result == INFERRED_STATIC_VARIABLE) {
entry.setValue(result, target, TargetedResult.EMPTY_LIST);
return true;
}
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index 04c4ec4..cb5791c 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -246,15 +246,6 @@
new ResultDescriptor<bool>('CREATED_RESOLVED_UNIT12', false);
/**
- * The flag specifying that [RESOLVED_UNIT13] has been been computed for this
- * compilation unit (without requiring that the AST for it still be in cache).
- *
- * The result is only available for [LibrarySpecificUnit]s.
- */
-final ResultDescriptor<bool> CREATED_RESOLVED_UNIT13 =
- new ResultDescriptor<bool>('CREATED_RESOLVED_UNIT13', false);
-
-/**
* The flag specifying that [RESOLVED_UNIT2] has been been computed for this
* compilation unit (without requiring that the AST for it still be in cache).
*
@@ -526,7 +517,7 @@
/**
* The partial [LibraryElement] associated with a library.
*
- * [LIBRARY_ELEMENT6] plus propagated types for propagable variables.
+ * [LIBRARY_ELEMENT6] plus [RESOLVED_UNIT7] for all library units.
*
* The result is only available for [Source]s representing a library.
*/
@@ -635,36 +626,6 @@
'PENDING_ERRORS', const <PendingError>[]);
/**
- * A list of the [VariableElement]s whose type should be known to propagate
- * the type of another variable (the target).
- *
- * The result is only available for [VariableElement]s.
- */
-final ListResultDescriptor<VariableElement> PROPAGABLE_VARIABLE_DEPENDENCIES =
- new ListResultDescriptor<VariableElement>(
- 'PROPAGABLE_VARIABLE_DEPENDENCIES', null);
-
-/**
- * A list of the [VariableElement]s defined in a unit whose type might be
- * propagated. This includes variables defined at the library level as well as
- * static and instance members inside classes.
- *
- * The result is only available for [LibrarySpecificUnit]s.
- */
-final ListResultDescriptor<VariableElement> PROPAGABLE_VARIABLES_IN_UNIT =
- new ListResultDescriptor<VariableElement>(
- 'PROPAGABLE_VARIABLES_IN_UNIT', null);
-
-/**
- * An propagable variable ([VariableElement]) whose type has been propagated.
- *
- * The result is only available for [VariableElement]s.
- */
-final ResultDescriptor<VariableElement> PROPAGATED_VARIABLE =
- new ResultDescriptor<VariableElement>('PROPAGATED_VARIABLE', null,
- cachingPolicy: ELEMENT_CACHING_POLICY);
-
-/**
* The flag specifying that [LIBRARY_ELEMENT2] is ready for a library and its
* import/export closure.
*
@@ -776,11 +737,9 @@
cachingPolicy: AST_REUSABLE_CACHING_POLICY);
/**
- * The partially resolved [CompilationUnit] associated with a compilation unit.
- *
- * In addition to what is true of a [RESOLVED_UNIT9], tasks that use this value
- * as an input can assume that the initializers of instance variables have been
- * re-resolved.
+ * The resolved [CompilationUnit] associated with a compilation unit in which
+ * the types of class members have been inferred in addition to everything that
+ * is true of a [RESOLVED_UNIT9].
*
* The result is only available for [LibrarySpecificUnit]s.
*/
@@ -789,9 +748,8 @@
cachingPolicy: AST_CACHING_POLICY);
/**
- * The resolved [CompilationUnit] associated with a compilation unit in which
- * the types of class members have been inferred in addition to everything that
- * is true of a [RESOLVED_UNIT10].
+ * The resolved [CompilationUnit] associated with a compilation unit, with
+ * constants not yet resolved.
*
* The result is only available for [LibrarySpecificUnit]s.
*/
@@ -801,7 +759,7 @@
/**
* The resolved [CompilationUnit] associated with a compilation unit, with
- * constants not yet resolved.
+ * constants resolved.
*
* The result is only available for [LibrarySpecificUnit]s.
*/
@@ -810,16 +768,6 @@
cachingPolicy: AST_CACHING_POLICY);
/**
- * The resolved [CompilationUnit] associated with a compilation unit, with
- * constants resolved.
- *
- * The result is only available for [LibrarySpecificUnit]s.
- */
-final ResultDescriptor<CompilationUnit> RESOLVED_UNIT13 =
- new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT13', null,
- cachingPolicy: AST_CACHING_POLICY);
-
-/**
* The partially resolved [CompilationUnit] associated with a compilation unit.
*
* In addition to what is true of a [RESOLVED_UNIT1], tasks that use this value
@@ -902,8 +850,7 @@
* The partially resolved [CompilationUnit] associated with a compilation unit.
*
* In addition to what is true of a [RESOLVED_UNIT7], tasks that use this value
- * as an input can assume that the types of final variables have been
- * propagated.
+ * as an input can assume that the types of static variables have been inferred.
*
* The result is only available for [LibrarySpecificUnit]s.
*/
@@ -915,7 +862,8 @@
* The partially resolved [CompilationUnit] associated with a compilation unit.
*
* In addition to what is true of a [RESOLVED_UNIT8], tasks that use this value
- * as an input can assume that the types of static variables have been inferred.
+ * as an input can assume that the initializers of instance variables have been
+ * re-resolved.
*
* The result is only available for [LibrarySpecificUnit]s.
*/
@@ -940,7 +888,6 @@
RESOLVED_UNIT10,
RESOLVED_UNIT11,
RESOLVED_UNIT12,
- RESOLVED_UNIT13,
RESOLVED_UNIT
];
@@ -2303,85 +2250,6 @@
}
/**
- * A task that computes the [PROPAGABLE_VARIABLE_DEPENDENCIES] for a variable.
- */
-class ComputePropagableVariableDependenciesTask
- extends InferStaticVariableTask {
- /**
- * The name of the [RESOLVED_UNIT7] input.
- */
- static const String UNIT_INPUT = 'UNIT_INPUT';
-
- static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
- 'ComputePropagableVariableDependenciesTask',
- createTask,
- buildInputs,
- <ResultDescriptor>[PROPAGABLE_VARIABLE_DEPENDENCIES]);
-
- ComputePropagableVariableDependenciesTask(
- InternalAnalysisContext context, VariableElement variable)
- : super(context, variable);
-
- @override
- TaskDescriptor get descriptor => DESCRIPTOR;
-
- @override
- void internalPerform() {
- //
- // Prepare inputs.
- //
- CompilationUnit unit = getRequiredInput(UNIT_INPUT);
- //
- // Compute dependencies.
- //
- VariableDeclaration declaration = getDeclaration(unit);
- VariableGatherer gatherer = new VariableGatherer(_isPropagable);
- declaration.initializer.accept(gatherer);
- //
- // Record outputs.
- //
- outputs[PROPAGABLE_VARIABLE_DEPENDENCIES] = gatherer.results.toList();
- }
-
- /**
- * Return `true` if the given [variable] is a variable whose type can be
- * propagated.
- */
- bool _isPropagable(VariableElement variable) =>
- variable is PropertyInducingElement &&
- (variable.isConst || variable.isFinal) &&
- variable.hasImplicitType &&
- variable.initializer != null;
-
- /**
- * Return a map from the names of the inputs of this kind of task to the task
- * input descriptors describing those inputs for a task with the
- * given [target].
- */
- static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
- if (target is VariableElement) {
- CompilationUnitElementImpl unit = target
- .getAncestor((Element element) => element is CompilationUnitElement);
- return <String, TaskInput>{
- UNIT_INPUT: RESOLVED_UNIT7
- .of(new LibrarySpecificUnit(unit.librarySource, unit.source))
- };
- }
- throw new AnalysisException(
- 'Cannot build inputs for a ${target.runtimeType}');
- }
-
- /**
- * Create a [ComputePropagableVariableDependenciesTask] based on the
- * given [target] in the given [context].
- */
- static ComputePropagableVariableDependenciesTask createTask(
- AnalysisContext context, AnalysisTarget target) {
- return new ComputePropagableVariableDependenciesTask(context, target);
- }
-}
-
-/**
* A task that builds [REQUIRED_CONSTANTS] for a unit.
*/
class ComputeRequiredConstantsTask extends SourceBasedAnalysisTask {
@@ -3006,11 +2874,11 @@
}
/**
- * A task that builds [RESOLVED_UNIT13] for a unit.
+ * A task that builds [RESOLVED_UNIT12] for a unit.
*/
class EvaluateUnitConstantsTask extends SourceBasedAnalysisTask {
/**
- * The name of the [RESOLVED_UNIT12] input.
+ * The name of the [RESOLVED_UNIT11] input.
*/
static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -3026,7 +2894,7 @@
'EvaluateUnitConstantsTask',
createTask,
buildInputs,
- <ResultDescriptor>[CREATED_RESOLVED_UNIT13, RESOLVED_UNIT13]);
+ <ResultDescriptor>[CREATED_RESOLVED_UNIT12, RESOLVED_UNIT12]);
EvaluateUnitConstantsTask(AnalysisContext context, LibrarySpecificUnit target)
: super(context, target);
@@ -3039,8 +2907,8 @@
// No actual work needs to be performed; the task manager will ensure that
// all constants are evaluated before this method is called.
CompilationUnit unit = getRequiredInput(UNIT_INPUT);
- outputs[RESOLVED_UNIT13] = unit;
- outputs[CREATED_RESOLVED_UNIT13] = true;
+ outputs[RESOLVED_UNIT12] = unit;
+ outputs[CREATED_RESOLVED_UNIT12] = true;
}
/**
@@ -3052,7 +2920,7 @@
LibrarySpecificUnit unit = target;
return <String, TaskInput>{
'libraryElement': LIBRARY_ELEMENT9.of(unit.library),
- UNIT_INPUT: RESOLVED_UNIT12.of(unit),
+ UNIT_INPUT: RESOLVED_UNIT11.of(unit),
CONSTANT_VALUES:
COMPILATION_UNIT_CONSTANTS.of(unit).toListOf(CONSTANT_VALUE),
'constantExpressionsDependencies':
@@ -3075,7 +2943,7 @@
*/
class GatherUsedImportedElementsTask extends SourceBasedAnalysisTask {
/**
- * The name of the [RESOLVED_UNIT12] input.
+ * The name of the [RESOLVED_UNIT11] input.
*/
static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -3119,7 +2987,7 @@
*/
static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
LibrarySpecificUnit unit = target;
- return <String, TaskInput>{UNIT_INPUT: RESOLVED_UNIT12.of(unit)};
+ return <String, TaskInput>{UNIT_INPUT: RESOLVED_UNIT11.of(unit)};
}
/**
@@ -3137,7 +3005,7 @@
*/
class GatherUsedLocalElementsTask extends SourceBasedAnalysisTask {
/**
- * The name of the [RESOLVED_UNIT12] input.
+ * The name of the [RESOLVED_UNIT11] input.
*/
static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -3181,7 +3049,7 @@
*/
static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
LibrarySpecificUnit unit = target;
- return <String, TaskInput>{UNIT_INPUT: RESOLVED_UNIT12.of(unit)};
+ return <String, TaskInput>{UNIT_INPUT: RESOLVED_UNIT11.of(unit)};
}
/**
@@ -3199,7 +3067,7 @@
*/
class GenerateHintsTask extends SourceBasedAnalysisTask {
/**
- * The name of the [RESOLVED_UNIT12] input.
+ * The name of the [RESOLVED_UNIT11] input.
*/
static const String RESOLVED_UNIT_INPUT = 'RESOLVED_UNIT';
@@ -3497,7 +3365,7 @@
static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT';
/**
- * The name of the input whose value is the [RESOLVED_UNIT9] for the
+ * The name of the input whose value is the [RESOLVED_UNIT8] for the
* compilation unit.
*/
static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -3509,7 +3377,7 @@
'InferInstanceMembersInUnitTask',
createTask,
buildInputs,
- <ResultDescriptor>[CREATED_RESOLVED_UNIT11, RESOLVED_UNIT11]);
+ <ResultDescriptor>[CREATED_RESOLVED_UNIT10, RESOLVED_UNIT10]);
/**
* Initialize a newly created task to build a library element for the given
@@ -3541,8 +3409,8 @@
//
// Record outputs.
//
- outputs[RESOLVED_UNIT11] = unit;
- outputs[CREATED_RESOLVED_UNIT11] = true;
+ outputs[RESOLVED_UNIT10] = unit;
+ outputs[CREATED_RESOLVED_UNIT10] = true;
}
/**
@@ -3553,7 +3421,7 @@
static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
LibrarySpecificUnit unit = target;
return <String, TaskInput>{
- UNIT_INPUT: RESOLVED_UNIT10.of(unit),
+ UNIT_INPUT: RESOLVED_UNIT9.of(unit),
TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
// In strong mode, add additional dependencies to enforce inference
// ordering.
@@ -3561,14 +3429,14 @@
// Require that field re-resolution be complete for all units in the
// current library cycle.
'orderLibraryCycleTasks': LIBRARY_CYCLE_UNITS.of(unit.library).toList(
- (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT10.of(
+ (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT9.of(
new LibrarySpecificUnit(
(unit as CompilationUnitElementImpl).librarySource,
unit.source))),
// Require that full inference be complete for all dependencies of the
// current library cycle.
'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit.library).toList(
- (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT11.of(
+ (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT10.of(
new LibrarySpecificUnit(
(unit as CompilationUnitElementImpl).librarySource,
unit.source)))
@@ -3672,8 +3540,8 @@
'InferStaticVariableTypesInUnitTask',
createTask,
buildInputs, <ResultDescriptor>[
- CREATED_RESOLVED_UNIT9,
- RESOLVED_UNIT9,
+ CREATED_RESOLVED_UNIT8,
+ RESOLVED_UNIT8,
STATIC_VARIABLE_RESOLUTION_ERRORS_IN_UNIT
]);
@@ -3700,8 +3568,8 @@
// because the work has implicitly been done by virtue of the task model
// preparing all of the inputs.
//
- outputs[RESOLVED_UNIT9] = unit;
- outputs[CREATED_RESOLVED_UNIT9] = true;
+ outputs[RESOLVED_UNIT8] = unit;
+ outputs[CREATED_RESOLVED_UNIT8] = true;
outputs[STATIC_VARIABLE_RESOLUTION_ERRORS_IN_UNIT] =
AnalysisError.mergeLists(errorLists);
}
@@ -3720,7 +3588,7 @@
ERRORS_LIST_INPUT: INFERABLE_STATIC_VARIABLES_IN_UNIT
.of(unit)
.toListOf(STATIC_VARIABLE_RESOLUTION_ERRORS),
- UNIT_INPUT: RESOLVED_UNIT8.of(unit)
+ UNIT_INPUT: RESOLVED_UNIT7.of(unit)
};
}
@@ -3848,14 +3716,14 @@
.of(variable)
.toListOf(INFERRED_STATIC_VARIABLE),
TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
- UNIT_INPUT: RESOLVED_UNIT8.of(unit),
+ UNIT_INPUT: RESOLVED_UNIT7.of(unit),
// In strong mode, add additional dependencies to enforce inference
// ordering.
// Require that full inference be complete for all dependencies of the
// current library cycle.
'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit.library).toList(
- (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT11.of(
+ (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT10.of(
new LibrarySpecificUnit(
(unit as CompilationUnitElementImpl).librarySource,
unit.source)))
@@ -4126,6 +3994,7 @@
RecordingErrorListener errorListener = new RecordingErrorListener();
Parser parser = new Parser(source, errorListener);
AnalysisOptions options = context.analysisOptions;
+ parser.enableAssertInitializer = options.enableAssertInitializer;
parser.parseAsync = options.enableAsync;
parser.parseFunctionBodies = options.analyzeFunctionBodiesPredicate(source);
parser.parseGenericMethods = options.enableGenericMethods;
@@ -4314,7 +4183,6 @@
createTask,
buildInputs, <ResultDescriptor>[
INFERABLE_STATIC_VARIABLES_IN_UNIT,
- PROPAGABLE_VARIABLES_IN_UNIT,
CREATED_RESOLVED_UNIT7,
RESOLVED_UNIT7
]);
@@ -4349,7 +4217,6 @@
} else {
outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT] = VariableElement.EMPTY_LIST;
}
- outputs[PROPAGABLE_VARIABLES_IN_UNIT] = visitor.propagableVariables;
outputs[RESOLVED_UNIT7] = unit;
outputs[CREATED_RESOLVED_UNIT7] = true;
}
@@ -4372,7 +4239,7 @@
// Require that full inference be complete for all dependencies of the
// current library cycle.
'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit.library).toList(
- (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT11.of(
+ (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT10.of(
new LibrarySpecificUnit(
(unit as CompilationUnitElementImpl).librarySource,
unit.source)))
@@ -4390,295 +4257,6 @@
}
/**
- * An artificial task that does nothing except to force propagated types for
- * all propagable variables in the import/export closure a library.
- */
-class PropagateVariableTypesInLibraryClosureTask
- extends SourceBasedAnalysisTask {
- /**
- * The name of the [LIBRARY_ELEMENT7] input.
- */
- static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
-
- /**
- * The task descriptor describing this kind of task.
- */
- static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
- 'PropagateVariableTypesInLibraryClosureTask',
- createTask,
- buildInputs,
- <ResultDescriptor>[LIBRARY_ELEMENT8]);
-
- PropagateVariableTypesInLibraryClosureTask(
- InternalAnalysisContext context, AnalysisTarget target)
- : super(context, target);
-
- @override
- TaskDescriptor get descriptor => DESCRIPTOR;
-
- @override
- void internalPerform() {
- LibraryElement library = getRequiredInput(LIBRARY_INPUT);
- outputs[LIBRARY_ELEMENT8] = library;
- }
-
- /**
- * Return a map from the names of the inputs of this kind of task to the task
- * input descriptors describing those inputs for a task with the
- * given [target].
- */
- static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
- Source source = target;
- return <String, TaskInput>{
- 'readyForClosure': READY_LIBRARY_ELEMENT7.of(source),
- LIBRARY_INPUT: LIBRARY_ELEMENT7.of(source),
- };
- }
-
- /**
- * Create a [PropagateVariableTypesInLibraryClosureTask] based on the given
- * [target] in the given [context].
- */
- static PropagateVariableTypesInLibraryClosureTask createTask(
- AnalysisContext context, AnalysisTarget target) {
- return new PropagateVariableTypesInLibraryClosureTask(context, target);
- }
-}
-
-/**
- * An artificial task that does nothing except to force propagated types for
- * all propagable variables in the defining and part units of a library.
- */
-class PropagateVariableTypesInLibraryTask extends SourceBasedAnalysisTask {
- /**
- * The name of the [LIBRARY_ELEMENT6] input.
- */
- static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
-
- /**
- * The task descriptor describing this kind of task.
- */
- static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
- 'PropagateVariableTypesInLibraryTask',
- createTask,
- buildInputs,
- <ResultDescriptor>[LIBRARY_ELEMENT7]);
-
- PropagateVariableTypesInLibraryTask(
- InternalAnalysisContext context, AnalysisTarget target)
- : super(context, target);
-
- @override
- TaskDescriptor get descriptor => DESCRIPTOR;
-
- @override
- void internalPerform() {
- LibraryElement library = getRequiredInput(LIBRARY_INPUT);
- outputs[LIBRARY_ELEMENT7] = library;
- }
-
- /**
- * Return a map from the names of the inputs of this kind of task to the task
- * input descriptors describing those inputs for a task with the
- * given [target].
- */
- static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
- Source source = target;
- return <String, TaskInput>{
- 'propagatedVariableTypesInUnits':
- LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT8),
- LIBRARY_INPUT: LIBRARY_ELEMENT6.of(source),
- };
- }
-
- /**
- * Create a [PropagateVariableTypesInLibraryTask] based on the given [target]
- * in the given [context].
- */
- static PropagateVariableTypesInLibraryTask createTask(
- AnalysisContext context, AnalysisTarget target) {
- return new PropagateVariableTypesInLibraryTask(context, target);
- }
-}
-
-/**
- * A task that ensures that all of the propagable variables in a compilation
- * unit have had their type propagated.
- */
-class PropagateVariableTypesInUnitTask extends SourceBasedAnalysisTask {
- /**
- * The name of the input whose value is the [RESOLVED_UNIT7] for the
- * compilation unit.
- */
- static const String UNIT_INPUT = 'UNIT_INPUT';
-
- /**
- * The task descriptor describing this kind of task.
- */
- static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
- 'PropagateVariableTypesInUnitTask',
- createTask,
- buildInputs,
- <ResultDescriptor>[CREATED_RESOLVED_UNIT8, RESOLVED_UNIT8]);
-
- PropagateVariableTypesInUnitTask(
- InternalAnalysisContext context, LibrarySpecificUnit unit)
- : super(context, unit);
-
- @override
- TaskDescriptor get descriptor => DESCRIPTOR;
-
- @override
- void internalPerform() {
- //
- // Prepare inputs.
- //
- CompilationUnit unit = getRequiredInput(UNIT_INPUT);
- //
- // Record outputs. There is no additional work to be done at this time
- // because the work has implicitly been done by virtue of the task model
- // preparing all of the inputs.
- //
- outputs[RESOLVED_UNIT8] = unit;
- outputs[CREATED_RESOLVED_UNIT8] = true;
- }
-
- /**
- * Return a map from the names of the inputs of this kind of task to the task
- * input descriptors describing those inputs for a task with the given
- * [target].
- */
- static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
- LibrarySpecificUnit unit = target;
- return <String, TaskInput>{
- 'variables':
- PROPAGABLE_VARIABLES_IN_UNIT.of(unit).toListOf(PROPAGATED_VARIABLE),
- UNIT_INPUT: RESOLVED_UNIT7.of(unit)
- };
- }
-
- /**
- * Create a [PropagateVariableTypesInUnitTask] based on the given [target]
- * in the given [context].
- */
- static PropagateVariableTypesInUnitTask createTask(
- AnalysisContext context, AnalysisTarget target) {
- return new PropagateVariableTypesInUnitTask(context, target);
- }
-}
-
-/**
- * A task that computes the propagated type of an propagable variable and
- * stores it in the element model.
- */
-class PropagateVariableTypeTask extends InferStaticVariableTask {
- /**
- * The name of the [TYPE_PROVIDER] input.
- */
- static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT';
-
- /**
- * The name of the [RESOLVED_UNIT7] input.
- */
- static const String UNIT_INPUT = 'UNIT_INPUT';
-
- static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
- 'PropagateVariableTypeTask',
- createTask,
- buildInputs,
- <ResultDescriptor>[PROPAGATED_VARIABLE]);
-
- PropagateVariableTypeTask(
- InternalAnalysisContext context, VariableElement variable)
- : super(context, variable);
-
- @override
- TaskDescriptor get descriptor => DESCRIPTOR;
-
- @override
- bool get handlesDependencyCycles => true;
-
- @override
- void internalPerform() {
- //
- // Prepare inputs.
- //
- PropertyInducingElementImpl variable = target;
- TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT);
- CompilationUnit unit = getRequiredInput(UNIT_INPUT);
-
- // If we're not in a dependency cycle, and we have no type annotation,
- // re-resolve the right hand side and do propagation.
- if (dependencyCycle == null && variable.hasImplicitType) {
- VariableDeclaration declaration = getDeclaration(unit);
- //
- // Re-resolve the variable's initializer with the propagated types of
- // other variables.
- //
- Expression initializer = declaration.initializer;
- ResolutionContext resolutionContext = ResolutionContextBuilder.contextFor(
- initializer, AnalysisErrorListener.NULL_LISTENER);
- ResolverVisitor visitor = new ResolverVisitor(variable.library,
- variable.source, typeProvider, AnalysisErrorListener.NULL_LISTENER,
- nameScope: resolutionContext.scope);
- if (resolutionContext.enclosingClassDeclaration != null) {
- visitor.prepareToResolveMembersInClass(
- resolutionContext.enclosingClassDeclaration);
- }
- visitor.initForIncrementalResolution();
- initializer.accept(visitor);
- //
- // Record the type of the variable.
- //
- DartType newType = initializer.bestType;
- if (newType != null && !newType.isBottom && !newType.isDynamic) {
- variable.propagatedType = newType;
- }
- }
- //
- // Record outputs.
- //
- outputs[PROPAGATED_VARIABLE] = variable;
- }
-
- /**
- * Return a map from the names of the inputs of this kind of task to the task
- * input descriptors describing those inputs for a task with the given
- * [target].
- */
- static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
- VariableElement variable = target;
- if (variable.library == null) {
- StringBuffer buffer = new StringBuffer();
- buffer.write(
- 'PropagateVariableTypeTask building inputs for a variable with no library. Variable name = "');
- buffer.write(variable.name);
- buffer.write('". Path = ');
- (variable as ElementImpl).appendPathTo(buffer);
- throw new AnalysisException(buffer.toString());
- }
- LibrarySpecificUnit unit =
- new LibrarySpecificUnit(variable.library.source, variable.source);
- return <String, TaskInput>{
- 'dependencies': PROPAGABLE_VARIABLE_DEPENDENCIES
- .of(variable)
- .toListOf(PROPAGATED_VARIABLE),
- TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
- UNIT_INPUT: RESOLVED_UNIT7.of(unit),
- };
- }
-
- /**
- * Create a [PropagateVariableTypeTask] based on the given [target] in the
- * given [context].
- */
- static PropagateVariableTypeTask createTask(
- AnalysisContext context, AnalysisTarget target) {
- return new PropagateVariableTypeTask(context, target);
- }
-}
-
-/**
* A task that ensures that [LIBRARY_ELEMENT2] is ready for the target library
* source and its import/export closure.
*/
@@ -4768,14 +4346,14 @@
* A task that ensures that [LIBRARY_ELEMENT7] is ready for the target library
* source and its import/export closure.
*/
-class ReadyLibraryElement6Task extends SourceBasedAnalysisTask {
+class ReadyLibraryElement7Task extends SourceBasedAnalysisTask {
static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
- 'ReadyLibraryElement6Task',
+ 'ReadyLibraryElement7Task',
createTask,
buildInputs,
<ResultDescriptor>[READY_LIBRARY_ELEMENT7]);
- ReadyLibraryElement6Task(
+ ReadyLibraryElement7Task(
InternalAnalysisContext context, AnalysisTarget target)
: super(context, target);
@@ -4801,9 +4379,9 @@
};
}
- static ReadyLibraryElement6Task createTask(
+ static ReadyLibraryElement7Task createTask(
AnalysisContext context, AnalysisTarget target) {
- return new ReadyLibraryElement6Task(context, target);
+ return new ReadyLibraryElement7Task(context, target);
}
}
@@ -5292,7 +4870,7 @@
'Cannot build inputs for a ${target.runtimeType}');
}
return <String, TaskInput>{
- 'createdResolvedUnit': CREATED_RESOLVED_UNIT12
+ 'createdResolvedUnit': CREATED_RESOLVED_UNIT11
.of(new LibrarySpecificUnit(librarySource, target.source))
};
}
@@ -5382,6 +4960,117 @@
}
/**
+ * An artificial task that does nothing except to force [LIBRARY_ELEMENT7] for
+ * the target library and its import/export closure.
+ */
+class ResolvedUnit7InLibraryClosureTask extends SourceBasedAnalysisTask {
+ /**
+ * The name of the [LIBRARY_ELEMENT7] input.
+ */
+ static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
+
+ /**
+ * The task descriptor describing this kind of task.
+ */
+ static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+ 'ResolvedUnit7InLibraryClosureTask',
+ createTask,
+ buildInputs,
+ <ResultDescriptor>[LIBRARY_ELEMENT8]);
+
+ ResolvedUnit7InLibraryClosureTask(
+ InternalAnalysisContext context, AnalysisTarget target)
+ : super(context, target);
+
+ @override
+ TaskDescriptor get descriptor => DESCRIPTOR;
+
+ @override
+ void internalPerform() {
+ LibraryElement library = getRequiredInput(LIBRARY_INPUT);
+ outputs[LIBRARY_ELEMENT8] = library;
+ }
+
+ /**
+ * Return a map from the names of the inputs of this kind of task to the task
+ * input descriptors describing those inputs for a task with the
+ * given [target].
+ */
+ static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
+ Source source = target;
+ return <String, TaskInput>{
+ 'readyForClosure': READY_LIBRARY_ELEMENT7.of(source),
+ LIBRARY_INPUT: LIBRARY_ELEMENT7.of(source),
+ };
+ }
+
+ /**
+ * Create a [ResolvedUnit7InLibraryClosureTask] based on the given
+ * [target] in the given [context].
+ */
+ static ResolvedUnit7InLibraryClosureTask createTask(
+ AnalysisContext context, AnalysisTarget target) {
+ return new ResolvedUnit7InLibraryClosureTask(context, target);
+ }
+}
+
+/**
+ * An artificial task that does nothing except to force [LIBRARY_ELEMENT6] and
+ * [RESOLVED_UNIT7] in the defining and part units of a library.
+ */
+class ResolvedUnit7InLibraryTask extends SourceBasedAnalysisTask {
+ /**
+ * The name of the [LIBRARY_ELEMENT6] input.
+ */
+ static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
+
+ /**
+ * The task descriptor describing this kind of task.
+ */
+ static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+ 'ResolvedUnit7InLibraryTask',
+ createTask,
+ buildInputs,
+ <ResultDescriptor>[LIBRARY_ELEMENT7]);
+
+ ResolvedUnit7InLibraryTask(
+ InternalAnalysisContext context, AnalysisTarget target)
+ : super(context, target);
+
+ @override
+ TaskDescriptor get descriptor => DESCRIPTOR;
+
+ @override
+ void internalPerform() {
+ LibraryElement library = getRequiredInput(LIBRARY_INPUT);
+ outputs[LIBRARY_ELEMENT7] = library;
+ }
+
+ /**
+ * Return a map from the names of the inputs of this kind of task to the task
+ * input descriptors describing those inputs for a task with the
+ * given [target].
+ */
+ static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
+ Source source = target;
+ return <String, TaskInput>{
+ 'resolvedUnits':
+ LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT7),
+ LIBRARY_INPUT: LIBRARY_ELEMENT6.of(source),
+ };
+ }
+
+ /**
+ * Create a [ResolvedUnit7InLibraryTask] based on the given [target]
+ * in the given [context].
+ */
+ static ResolvedUnit7InLibraryTask createTask(
+ AnalysisContext context, AnalysisTarget target) {
+ return new ResolvedUnit7InLibraryTask(context, target);
+ }
+}
+
+/**
* A task that ensures that all of the inferable instance members in a
* compilation unit have had their right hand sides re-resolved
*/
@@ -5397,7 +5086,7 @@
static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT';
/**
- * The name of the input whose value is the [RESOLVED_UNIT9] for the
+ * The name of the input whose value is the [RESOLVED_UNIT8] for the
* compilation unit.
*/
static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -5409,7 +5098,7 @@
'ResolveInstanceFieldsInUnitTask',
createTask,
buildInputs,
- <ResultDescriptor>[CREATED_RESOLVED_UNIT10, RESOLVED_UNIT10]);
+ <ResultDescriptor>[CREATED_RESOLVED_UNIT9, RESOLVED_UNIT9]);
/**
* Initialize a newly created task to build a library element for the given
@@ -5446,8 +5135,8 @@
//
// Record outputs.
//
- outputs[RESOLVED_UNIT10] = unit;
- outputs[CREATED_RESOLVED_UNIT10] = true;
+ outputs[RESOLVED_UNIT9] = unit;
+ outputs[CREATED_RESOLVED_UNIT9] = true;
}
/**
@@ -5458,7 +5147,7 @@
static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
LibrarySpecificUnit unit = target;
return <String, TaskInput>{
- UNIT_INPUT: RESOLVED_UNIT9.of(unit),
+ UNIT_INPUT: RESOLVED_UNIT8.of(unit),
LIBRARY_INPUT: LIBRARY_ELEMENT6.of(unit.library),
TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
// In strong mode, add additional dependencies to enforce inference
@@ -5467,14 +5156,14 @@
// Require that static variable inference be complete for all units in
// the current library cycle.
'orderLibraryCycleTasks': LIBRARY_CYCLE_UNITS.of(unit.library).toList(
- (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT9.of(
+ (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT8.of(
new LibrarySpecificUnit(
(unit as CompilationUnitElementImpl).librarySource,
unit.source))),
// Require that full inference be complete for all dependencies of the
// current library cycle.
'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit.library).toList(
- (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT11.of(
+ (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT10.of(
new LibrarySpecificUnit(
(unit as CompilationUnitElementImpl).librarySource,
unit.source)))
@@ -5492,7 +5181,7 @@
}
/**
- * A task that finishes resolution by requesting [RESOLVED_UNIT12] for every
+ * A task that finishes resolution by requesting [RESOLVED_UNIT11] for every
* unit in the libraries closure and produces [LIBRARY_ELEMENT9].
*/
class ResolveLibraryReferencesTask extends SourceBasedAnalysisTask {
@@ -5533,7 +5222,7 @@
return <String, TaskInput>{
LIBRARY_INPUT: LIBRARY_ELEMENT8.of(source),
'resolvedUnits':
- LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT12),
+ LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT11),
};
}
@@ -5548,7 +5237,7 @@
}
/**
- * A task that finishes resolution by requesting [RESOLVED_UNIT13] for every
+ * A task that finishes resolution by requesting [RESOLVED_UNIT12] for every
* unit in the libraries closure and produces [LIBRARY_ELEMENT].
*/
class ResolveLibraryTask extends SourceBasedAnalysisTask {
@@ -5558,7 +5247,7 @@
static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
/**
- * The name of the list of [RESOLVED_UNIT13] input.
+ * The name of the list of [RESOLVED_UNIT12] input.
*/
static const String UNITS_INPUT = 'UNITS_INPUT';
@@ -5858,7 +5547,7 @@
static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT';
/**
- * The name of the [RESOLVED_UNIT11] input.
+ * The name of the [RESOLVED_UNIT10] input.
*/
static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -5866,8 +5555,8 @@
'ResolveUnitTask', createTask, buildInputs, <ResultDescriptor>[
CONSTANT_EXPRESSIONS_DEPENDENCIES,
RESOLVE_UNIT_ERRORS,
- CREATED_RESOLVED_UNIT12,
- RESOLVED_UNIT12
+ CREATED_RESOLVED_UNIT11,
+ RESOLVED_UNIT11
]);
ResolveUnitTask(
@@ -5913,8 +5602,8 @@
//
outputs[CONSTANT_EXPRESSIONS_DEPENDENCIES] = constExprDependencies;
outputs[RESOLVE_UNIT_ERRORS] = getTargetSourceErrors(errorListener, target);
- outputs[RESOLVED_UNIT12] = unit;
- outputs[CREATED_RESOLVED_UNIT12] = true;
+ outputs[RESOLVED_UNIT11] = unit;
+ outputs[CREATED_RESOLVED_UNIT11] = true;
}
/**
@@ -5927,14 +5616,14 @@
return <String, TaskInput>{
LIBRARY_INPUT: LIBRARY_ELEMENT8.of(unit.library),
TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
- UNIT_INPUT: RESOLVED_UNIT11.of(unit),
+ UNIT_INPUT: RESOLVED_UNIT10.of(unit),
// In strong mode, add additional dependencies to enforce inference
// ordering.
// Require that inference be complete for all units in the
// current library cycle.
'orderLibraryCycleTasks': LIBRARY_CYCLE_UNITS.of(unit.library).toList(
- (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT11.of(
+ (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT10.of(
new LibrarySpecificUnit(
(unit as CompilationUnitElementImpl).librarySource,
unit.source)))
@@ -6289,7 +5978,7 @@
*/
class StrongModeVerifyUnitTask extends SourceBasedAnalysisTask {
/**
- * The name of the [RESOLVED_UNIT13] input.
+ * The name of the [RESOLVED_UNIT12] input.
*/
static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -6350,7 +6039,7 @@
static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
LibrarySpecificUnit unit = target;
return <String, TaskInput>{
- UNIT_INPUT: RESOLVED_UNIT13.of(unit),
+ UNIT_INPUT: RESOLVED_UNIT12.of(unit),
TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
};
}
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart
index 6cf5585..dd544ca 100644
--- a/pkg/analyzer/lib/src/task/options.dart
+++ b/pkg/analyzer/lib/src/task/options.dart
@@ -45,6 +45,7 @@
/// `analyzer` analysis options constants.
class AnalyzerOptions {
static const String analyzer = 'analyzer';
+ static const String enableAssertInitializer = 'enableAssertInitializer';
static const String enableAsync = 'enableAsync';
static const String enableGenericMethods = 'enableGenericMethods';
static const String enableStrictCallChecks = 'enableStrictCallChecks';
@@ -84,6 +85,7 @@
/// Supported `analyzer` language configuration options.
static const List<String> languageOptions = const [
+ enableAssertInitializer,
enableAsync,
enableGenericMethods,
enableStrictCallChecks,
@@ -478,6 +480,14 @@
void setLanguageOption(
AnalysisContext context, Object feature, Object value) {
+ if (feature == AnalyzerOptions.enableAssertInitializer) {
+ if (isTrue(value)) {
+ AnalysisOptionsImpl options =
+ new AnalysisOptionsImpl.from(context.analysisOptions);
+ options.enableAssertInitializer = true;
+ context.analysisOptions = options;
+ }
+ }
if (feature == AnalyzerOptions.enableAsync) {
if (isFalse(value)) {
AnalysisOptionsImpl options =
@@ -552,13 +562,13 @@
AnalysisOptionsImpl options, Object feature, Object value) {
bool boolValue = toBool(value);
if (boolValue != null) {
- if (feature == AnalyzerOptions.enableAsync) {
+ if (feature == AnalyzerOptions.enableAssertInitializer) {
+ options.enableAssertInitializer = boolValue;
+ } else if (feature == AnalyzerOptions.enableAsync) {
options.enableAsync = boolValue;
- }
- if (feature == AnalyzerOptions.enableSuperMixins) {
+ } else if (feature == AnalyzerOptions.enableSuperMixins) {
options.enableSuperMixins = boolValue;
- }
- if (feature == AnalyzerOptions.enableGenericMethods) {
+ } else if (feature == AnalyzerOptions.enableGenericMethods) {
options.enableGenericMethods = boolValue;
}
}
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index a623b1c..d0b55fe 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -186,7 +186,9 @@
// so no need to insert an error for this here.
continue;
}
- checkArgument(arg, _elementType(element));
+ DartType expectedType = _elementType(element);
+ if (expectedType == null) expectedType = DynamicTypeImpl.instance;
+ checkArgument(arg, expectedType);
}
}
@@ -699,28 +701,34 @@
assert(functionType.namedParameterTypes.isEmpty);
assert(functionType.optionalParameterTypes.isEmpty);
- // Refine the return type.
+ // Check the LHS type.
var rhsType = _getDefiniteType(expr.rightHandSide);
var lhsType = _getDefiniteType(expr.leftHandSide);
var returnType = rules.refineBinaryExpressionType(
typeProvider, lhsType, op, rhsType, functionType.returnType);
- // Check the argument for an implicit cast.
- _checkDowncast(expr.rightHandSide, paramTypes[0], from: rhsType);
-
- // Check the return type for an implicit cast.
- //
- // If needed, mark the left side to indicate a down cast when we assign
- // back to it. So these two implicit casts are equivalent:
- //
- // y = /*implicit cast*/(y + 42);
- // y/*implicit cast*/ += 42;
- //
- // TODO(jmesserly): this is an unambiguous way to represent it, but it's
- // a bit sneaky. We can't use the rightHandSide because that could be a
- // downcast on its own, and we can't use the entire expression because its
- // result value could used and then implicitly downcast.
- _checkDowncast(expr.leftHandSide, lhsType, from: returnType);
+ if (!rules.isSubtypeOf(returnType, lhsType)) {
+ final numType = typeProvider.numType;
+ // TODO(jmesserly): this seems to duplicate logic in StaticTypeAnalyzer.
+ // Try to fix up the numerical case if possible.
+ if (rules.isSubtypeOf(lhsType, numType) &&
+ rules.isSubtypeOf(lhsType, rhsType)) {
+ // This is also slightly different from spec, but allows us to keep
+ // compound operators in the int += num and num += dynamic cases.
+ _recordImplicitCast(expr.rightHandSide, rhsType, lhsType);
+ } else {
+ // TODO(jmesserly): this results in a duplicate error, because
+ // ErrorVerifier also reports it.
+ _recordMessage(expr, StrongModeCode.STATIC_TYPE_ERROR,
+ [expr, returnType, lhsType]);
+ }
+ } else {
+ // Check the RHS type.
+ //
+ // This is only needed if we didn't already need a cast, and avoids
+ // emitting two messages for the same expression.
+ _checkDowncast(expr.rightHandSide, paramTypes.first);
+ }
}
}
diff --git a/pkg/analyzer/test/generated/analysis_context_factory.dart b/pkg/analyzer/test/generated/analysis_context_factory.dart
index 1e48058..48234e1 100644
--- a/pkg/analyzer/test/generated/analysis_context_factory.dart
+++ b/pkg/analyzer/test/generated/analysis_context_factory.dart
@@ -18,7 +18,6 @@
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/java_engine_io.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source_io.dart';
diff --git a/pkg/analyzer/test/generated/incremental_resolver_test.dart b/pkg/analyzer/test/generated/incremental_resolver_test.dart
index 10c227e..d8a3c72 100644
--- a/pkg/analyzer/test/generated/incremental_resolver_test.dart
+++ b/pkg/analyzer/test/generated/incremental_resolver_test.dart
@@ -1938,9 +1938,8 @@
_assertCacheUnitResult(RESOLVED_UNIT9);
_assertCacheUnitResult(RESOLVED_UNIT10);
_assertCacheUnitResult(RESOLVED_UNIT11);
- _assertCacheUnitResult(RESOLVED_UNIT12);
if (expectCachePostConstantsValid) {
- _assertCacheUnitResult(RESOLVED_UNIT13);
+ _assertCacheUnitResult(RESOLVED_UNIT12);
_assertCacheUnitResult(RESOLVED_UNIT);
}
}
diff --git a/pkg/analyzer/test/generated/inheritance_manager_test.dart b/pkg/analyzer/test/generated/inheritance_manager_test.dart
index 1ac3a31..4d01088 100644
--- a/pkg/analyzer/test/generated/inheritance_manager_test.dart
+++ b/pkg/analyzer/test/generated/inheritance_manager_test.dart
@@ -13,7 +13,6 @@
import 'package:analyzer/src/dart/resolver/inheritance_manager.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error.dart';
-import 'package:analyzer/src/generated/java_engine_io.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/generated/testing/ast_factory.dart';
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index e48c4dc..1224141 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -2772,6 +2772,12 @@
static bool parseFunctionBodies = true;
/**
+ * A flag indicating whether the parser is to parse asserts in the initializer
+ * list of a constructor.
+ */
+ bool enableAssertInitializer = false;
+
+ /**
* A flag indicating whether parser is to parse async.
*/
bool parseAsync = true;
@@ -2844,6 +2850,7 @@
// Parse the source.
//
Parser parser = createParser(listener);
+ parser.enableAssertInitializer = enableAssertInitializer;
parser.parseAsync = parseAsync;
parser.parseGenericMethods = enableGenericMethods;
parser.parseGenericMethodComments = enableGenericMethodComments;
@@ -2973,6 +2980,7 @@
listener.setLineInfo(new TestSource(), scanner.lineStarts);
Token token = scanner.tokenize();
Parser parser = createParser(listener);
+ parser.enableAssertInitializer = enableAssertInitializer;
parser.parseAsync = parseAsync;
parser.parseFunctionBodies = parseFunctionBodies;
parser.parseGenericMethods = enableGenericMethods;
@@ -7094,6 +7102,16 @@
// null, null, null, null, null, null}, "");
}
+ void test_parseConstructor_assert() {
+ enableAssertInitializer = true;
+ ClassMember classMember = parse("parseClassMember", <Object>["C"],
+ "C(x, y) : _x = x, assert (x < y), _y = y;");
+ expect(classMember, new isInstanceOf<ConstructorDeclaration>());
+ ConstructorDeclaration constructor = classMember as ConstructorDeclaration;
+ NodeList<ConstructorInitializer> initializers = constructor.initializers;
+ expect(initializers, hasLength(2));
+ }
+
void test_parseConstructor_with_pseudo_function_literal() {
// "(b) {}" should not be misinterpreted as a function literal even though
// it looks like one.
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index 1135a52..cd87a6f 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -18,7 +18,6 @@
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/java_core.dart';
-import 'package:analyzer/src/generated/java_engine_io.dart';
import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source_io.dart';
@@ -1482,109 +1481,6 @@
expect(identifier.propagatedType.name, "CanvasRenderingContext2D");
}
- void test_finalPropertyInducingVariable_classMember_instance() {
- addNamedSource(
- "/lib.dart",
- r'''
-class A {
- final v = 0;
-}''');
- String code = r'''
-import 'lib.dart';
-f(A a) {
- return a.v; // marker
-}''';
- assertTypeOfMarkedExpression(
- code, typeProvider.dynamicType, typeProvider.intType);
- }
-
- void test_finalPropertyInducingVariable_classMember_instance_inherited() {
- addNamedSource(
- "/lib.dart",
- r'''
-class A {
- final v = 0;
-}''');
- String code = r'''
-import 'lib.dart';
-class B extends A {
- m() {
- return v; // marker
- }
-}''';
- assertTypeOfMarkedExpression(
- code, typeProvider.dynamicType, typeProvider.intType);
- }
-
- void
- test_finalPropertyInducingVariable_classMember_instance_propagatedTarget() {
- addNamedSource(
- "/lib.dart",
- r'''
-class A {
- final v = 0;
-}''');
- String code = r'''
-import 'lib.dart';
-f(p) {
- if (p is A) {
- return p.v; // marker
- }
-}''';
- assertTypeOfMarkedExpression(
- code, typeProvider.dynamicType, typeProvider.intType);
- }
-
- void test_finalPropertyInducingVariable_classMember_instance_unprefixed() {
- String code = r'''
-class A {
- final v = 0;
- m() {
- v; // marker
- }
-}''';
- assertTypeOfMarkedExpression(
- code, typeProvider.dynamicType, typeProvider.intType);
- }
-
- void test_finalPropertyInducingVariable_classMember_static() {
- addNamedSource(
- "/lib.dart",
- r'''
-class A {
- static final V = 0;
-}''');
- String code = r'''
-import 'lib.dart';
-f() {
- return A.V; // marker
-}''';
- assertTypeOfMarkedExpression(
- code, typeProvider.dynamicType, typeProvider.intType);
- }
-
- void test_finalPropertyInducingVariable_topLevelVariable_prefixed() {
- addNamedSource("/lib.dart", "final V = 0;");
- String code = r'''
-import 'lib.dart' as p;
-f() {
- var v2 = p.V; // marker prefixed
-}''';
- assertTypeOfMarkedExpression(
- code, typeProvider.dynamicType, typeProvider.intType);
- }
-
- void test_finalPropertyInducingVariable_topLevelVariable_simple() {
- addNamedSource("/lib.dart", "final V = 0;");
- String code = r'''
-import 'lib.dart';
-f() {
- return V; // marker simple
-}''';
- assertTypeOfMarkedExpression(
- code, typeProvider.dynamicType, typeProvider.intType);
- }
-
void test_forEach() {
String code = r'''
main() {
diff --git a/pkg/analyzer/test/src/context/builder_test.dart b/pkg/analyzer/test/src/context/builder_test.dart
index e43d56f..5fde200 100644
--- a/pkg/analyzer/test/src/context/builder_test.dart
+++ b/pkg/analyzer/test/src/context/builder_test.dart
@@ -6,15 +6,18 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/plugin/options.dart';
import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/context/builder.dart';
import 'package:analyzer/src/context/source.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/plugin/options_plugin.dart';
import 'package:package_config/packages.dart';
import 'package:package_config/src/packages_impl.dart';
import 'package:path/path.dart' as path;
+import 'package:plugin/src/plugin_impl.dart';
import 'package:unittest/unittest.dart';
import '../../embedder_tests.dart';
@@ -485,7 +488,8 @@
- empty_constructor_bodies
''');
- AnalysisOptions options = builder.getAnalysisOptions(path);
+ AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
+ AnalysisOptions options = builder.getAnalysisOptions(context, path);
_expectEqualOptions(options, expected);
}
@@ -505,8 +509,43 @@
enableAsync : true
''');
- AnalysisOptions options = builder.getAnalysisOptions(path);
- _expectEqualOptions(options, expected);
+ AnalysisEngine engine = AnalysisEngine.instance;
+ OptionsPlugin plugin = engine.optionsPlugin;
+ plugin.registerExtensionPoints((_) {});
+ try {
+ _TestOptionsProcessor processor = new _TestOptionsProcessor();
+ processor.expectedOptions = <String, Object>{
+ 'analyzer': {'enableAsync': true}
+ };
+ (plugin.optionsProcessorExtensionPoint as ExtensionPointImpl)
+ .add(processor);
+ AnalysisContext context = engine.createAnalysisContext();
+ AnalysisOptions options = builder.getAnalysisOptions(context, path);
+ _expectEqualOptions(options, expected);
+ } finally {
+ plugin.registerExtensionPoints((_) {});
+ }
+ }
+
+ void test_getAnalysisOptions_invalid() {
+ String path = '/some/directory/path';
+ String filePath = '$path/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}';
+ resourceProvider.newFile(filePath, ';');
+
+ AnalysisEngine engine = AnalysisEngine.instance;
+ OptionsPlugin plugin = engine.optionsPlugin;
+ plugin.registerExtensionPoints((_) {});
+ try {
+ _TestOptionsProcessor processor = new _TestOptionsProcessor();
+ (plugin.optionsProcessorExtensionPoint as ExtensionPointImpl)
+ .add(processor);
+ AnalysisContext context = engine.createAnalysisContext();
+ AnalysisOptions options = builder.getAnalysisOptions(context, path);
+ expect(options, isNotNull);
+ expect(processor.errorCount, 1);
+ } finally {
+ plugin.registerExtensionPoints((_) {});
+ }
}
void test_getAnalysisOptions_noDefault_noOverrides() {
@@ -520,7 +559,8 @@
- empty_constructor_bodies
''');
- AnalysisOptions options = builder.getAnalysisOptions(path);
+ AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
+ AnalysisOptions options = builder.getAnalysisOptions(context, path);
_expectEqualOptions(options, new AnalysisOptionsImpl());
}
@@ -536,7 +576,8 @@
enableAsync : true
''');
- AnalysisOptions options = builder.getAnalysisOptions(path);
+ AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
+ AnalysisOptions options = builder.getAnalysisOptions(context, path);
_expectEqualOptions(options, expected);
}
@@ -651,3 +692,27 @@
expect(locator.embedderYamls, hasLength(1));
}
}
+
+class _TestOptionsProcessor implements OptionsProcessor {
+ Map<String, Object> expectedOptions = null;
+
+ int errorCount = 0;
+
+ @override
+ void onError(Exception exception) {
+ errorCount++;
+ }
+
+ @override
+ void optionsProcessed(AnalysisContext context, Map<String, Object> options) {
+ if (expectedOptions == null) {
+ fail('Unexpected invocation of optionsProcessed');
+ }
+ expect(options, hasLength(expectedOptions.length));
+ for (String key in expectedOptions.keys) {
+ expect(options.containsKey(key), isTrue, reason: 'missing key $key');
+ expect(options[key], expectedOptions[key],
+ reason: 'values for key $key do not match');
+ }
+ }
+}
diff --git a/pkg/analyzer/test/src/context/context_test.dart b/pkg/analyzer/test/src/context/context_test.dart
index 42b91f8..456d3ed 100644
--- a/pkg/analyzer/test/src/context/context_test.dart
+++ b/pkg/analyzer/test/src/context/context_test.dart
@@ -2476,7 +2476,6 @@
entry.setState(RESOLVED_UNIT10, CacheState.FLUSHED);
entry.setState(RESOLVED_UNIT11, CacheState.FLUSHED);
entry.setState(RESOLVED_UNIT12, CacheState.FLUSHED);
- entry.setState(RESOLVED_UNIT13, CacheState.FLUSHED);
entry.setState(RESOLVED_UNIT, CacheState.FLUSHED);
context.resolveCompilationUnit2(source, source);
@@ -3797,10 +3796,10 @@
{
Expression argument = find42();
expect(argument.staticParameterElement, isNull);
- expect(argument.propagatedParameterElement, isNotNull);
}
+
// Update a.dart: add type annotation for 'a'.
- // '42' has 'staticParameterElement', but not 'propagatedParameterElement'.
+ // '42' has 'staticParameterElement'.
context.setContents(
a,
r'''
@@ -3816,10 +3815,10 @@
{
Expression argument = find42();
expect(argument.staticParameterElement, isNotNull);
- expect(argument.propagatedParameterElement, isNull);
}
+
// Update a.dart: remove type annotation for 'a'.
- // '42' has 'propagatedParameterElement', but not 'staticParameterElement'.
+ // '42' doesn't have 'staticParameterElement'.
context.setContents(
a,
r'''
@@ -3835,7 +3834,6 @@
{
Expression argument = find42();
expect(argument.staticParameterElement, isNull);
- expect(argument.propagatedParameterElement, isNotNull);
}
}
diff --git a/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart b/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
index b034228..4b6f6d5 100644
--- a/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
+++ b/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
@@ -48,18 +48,6 @@
@override
@failingTest
- test_field_propagated_type_final_immediate() {
- super.test_field_propagated_type_final_immediate();
- }
-
- @override
- @failingTest
- test_fully_linked_references_follow_other_references() {
- super.test_fully_linked_references_follow_other_references();
- }
-
- @override
- @failingTest
test_implicit_dependencies_follow_other_dependencies() {
super.test_implicit_dependencies_follow_other_dependencies();
}
@@ -120,18 +108,6 @@
@override
@failingTest
- test_linked_reference_reuse() {
- super.test_linked_reference_reuse();
- }
-
- @override
- @failingTest
- test_linked_type_dependency_reuse() {
- super.test_linked_type_dependency_reuse();
- }
-
- @override
- @failingTest
test_syntheticFunctionType_genericClosure() {
super.test_syntheticFunctionType_genericClosure();
}
@@ -156,37 +132,7 @@
@override
@failingTest
- test_syntheticFunctionType_noArguments() {
- super.test_syntheticFunctionType_noArguments();
- }
-
- @override
- @failingTest
- test_syntheticFunctionType_withArguments() {
- super.test_syntheticFunctionType_withArguments();
- }
-
- @override
- @failingTest
test_unused_type_parameter() {
super.test_unused_type_parameter();
}
-
- @override
- @failingTest
- test_variable_propagated_type_final_immediate() {
- super.test_variable_propagated_type_final_immediate();
- }
-
- @override
- @failingTest
- test_variable_propagated_type_new_reference() {
- super.test_variable_propagated_type_new_reference();
- }
-
- @override
- @failingTest
- test_variable_propagated_type_omit_dynamic() {
- super.test_variable_propagated_type_omit_dynamic();
- }
}
diff --git a/pkg/analyzer/test/src/summary/summarize_ast_test.dart b/pkg/analyzer/test/src/summary/summarize_ast_test.dart
index b24daf9..03c638e 100644
--- a/pkg/analyzer/test/src/summary/summarize_ast_test.dart
+++ b/pkg/analyzer/test/src/summary/summarize_ast_test.dart
@@ -65,18 +65,6 @@
@override
@failingTest
- test_field_propagated_type_final_immediate() {
- super.test_field_propagated_type_final_immediate();
- }
-
- @override
- @failingTest
- test_fully_linked_references_follow_other_references() {
- super.test_fully_linked_references_follow_other_references();
- }
-
- @override
- @failingTest
test_implicit_dependencies_follow_other_dependencies() {
super.test_implicit_dependencies_follow_other_dependencies();
}
@@ -119,18 +107,6 @@
@override
@failingTest
- test_linked_reference_reuse() {
- super.test_linked_reference_reuse();
- }
-
- @override
- @failingTest
- test_linked_type_dependency_reuse() {
- super.test_linked_type_dependency_reuse();
- }
-
- @override
- @failingTest
test_syntheticFunctionType_inGenericClass() {
super.test_syntheticFunctionType_inGenericClass();
}
@@ -143,39 +119,9 @@
@override
@failingTest
- test_syntheticFunctionType_noArguments() {
- super.test_syntheticFunctionType_noArguments();
- }
-
- @override
- @failingTest
- test_syntheticFunctionType_withArguments() {
- super.test_syntheticFunctionType_withArguments();
- }
-
- @override
- @failingTest
test_unused_type_parameter() {
super.test_unused_type_parameter();
}
-
- @override
- @failingTest
- test_variable_propagated_type_final_immediate() {
- super.test_variable_propagated_type_final_immediate();
- }
-
- @override
- @failingTest
- test_variable_propagated_type_new_reference() {
- super.test_variable_propagated_type_new_reference();
- }
-
- @override
- @failingTest
- test_variable_propagated_type_omit_dynamic() {
- super.test_variable_propagated_type_omit_dynamic();
- }
}
/**
diff --git a/pkg/analyzer/test/src/summary/summary_common.dart b/pkg/analyzer/test/src/summary/summary_common.dart
index 287b482..5d9d9a7 100644
--- a/pkg/analyzer/test/src/summary/summary_common.dart
+++ b/pkg/analyzer/test/src/summary/summary_common.dart
@@ -7733,12 +7733,6 @@
expect(v.inferredTypeSlot, 0);
}
- test_field_propagated_type_final_immediate() {
- UnlinkedVariable v =
- serializeClassText('class C { final v = 0; }').fields[0];
- checkLinkedTypeSlot(v.propagatedTypeSlot, 'dart:core', 'dart:core', 'int');
- }
-
test_field_static() {
UnlinkedVariable variable =
serializeClassText('class C { static int i; }').fields[0];
@@ -7788,11 +7782,11 @@
}
test_fully_linked_references_follow_other_references() {
- if (skipFullyLinkedData) {
+ if (!strongMode || skipFullyLinkedData) {
return;
}
serializeLibraryText('final x = 0; String y;');
- checkLinkedTypeSlot(unlinkedUnits[0].variables[0].propagatedTypeSlot,
+ checkLinkedTypeSlot(unlinkedUnits[0].variables[0].inferredTypeSlot,
'dart:core', 'dart:core', 'int');
checkTypeRef(
unlinkedUnits[0].variables[1].type, 'dart:core', 'dart:core', 'String');
@@ -7800,7 +7794,7 @@
// type reference for x should use a higher numbered reference than the
// unlinked type reference for y.
EntityRef propagatedType =
- getTypeRefForSlot(unlinkedUnits[0].variables[0].propagatedTypeSlot);
+ getTypeRefForSlot(unlinkedUnits[0].variables[0].inferredTypeSlot);
expect(unlinkedUnits[0].variables[1].type.reference,
lessThan(propagatedType.reference));
}
@@ -8712,7 +8706,7 @@
}
test_linked_reference_reuse() {
- if (skipFullyLinkedData) {
+ if (!strongMode || skipFullyLinkedData) {
return;
}
// When the reference for a linked type is the same as an explicitly
@@ -8722,12 +8716,12 @@
serializeLibraryText(
'import "a.dart"; import "b.dart"; C c1; final c2 = f();');
int explicitReference = findVariable('c1').type.reference;
- expect(getTypeRefForSlot(findVariable('c2').propagatedTypeSlot).reference,
+ expect(getTypeRefForSlot(findVariable('c2').inferredTypeSlot).reference,
explicitReference);
}
test_linked_type_dependency_reuse() {
- if (skipFullyLinkedData) {
+ if (!strongMode || skipFullyLinkedData) {
return;
}
// When the dependency for a linked type is the same as an explicit
@@ -8739,7 +8733,7 @@
int cReference = findVariable('c').type.reference;
int explicitDependency = linked.units[0].references[cReference].dependency;
int dReference =
- getTypeRefForSlot(findVariable('d').propagatedTypeSlot).reference;
+ getTypeRefForSlot(findVariable('d').inferredTypeSlot).reference;
expect(
linked.units[0].references[dReference].dependency, explicitDependency);
}
@@ -9500,8 +9494,8 @@
// ids should be reused.
addNamedSource('/a.dart', 'part of foo; final v = 0;');
serializeLibraryText('library foo; part "a.dart"; final w = 0;');
- expect(unlinkedUnits[1].variables[0].propagatedTypeSlot,
- unlinkedUnits[0].variables[0].propagatedTypeSlot);
+ expect(unlinkedUnits[1].variables[0].inferredTypeSlot,
+ unlinkedUnits[0].variables[0].inferredTypeSlot);
}
test_syntheticFunctionType_genericClosure() {
@@ -9592,38 +9586,6 @@
checkParamTypeRef(inferredType.syntheticParams[1].type, 1);
}
- test_syntheticFunctionType_noArguments() {
- if (skipFullyLinkedData) {
- return;
- }
- UnlinkedVariable variable = serializeVariableText('''
-final v = f() ? () => 0 : () => 1;
-bool f() => true;
-''');
- EntityRef propagatedType = getTypeRefForSlot(variable.propagatedTypeSlot);
- checkLinkedTypeRef(
- propagatedType.syntheticReturnType, 'dart:core', 'dart:core', 'int');
- expect(propagatedType.syntheticParams, isEmpty);
- }
-
- test_syntheticFunctionType_withArguments() {
- if (skipFullyLinkedData) {
- return;
- }
- UnlinkedVariable variable = serializeVariableText('''
-final v = f() ? (int x, String y) => 0 : (int x, String y) => 1;
-bool f() => true;
-''');
- EntityRef propagatedType = getTypeRefForSlot(variable.propagatedTypeSlot);
- checkTypeRef(
- propagatedType.syntheticReturnType, 'dart:core', 'dart:core', 'int');
- expect(propagatedType.syntheticParams, hasLength(2));
- checkTypeRef(propagatedType.syntheticParams[0].type, 'dart:core',
- 'dart:core', 'int');
- checkTypeRef(propagatedType.syntheticParams[1].type, 'dart:core',
- 'dart:core', 'String');
- }
-
test_type_arguments_explicit() {
EntityRef typeRef = serializeTypeText('List<int>');
checkTypeRef(typeRef, 'dart:core', 'dart:core', 'List',
@@ -10335,59 +10297,6 @@
expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
}
- test_variable_propagated_type_final_immediate() {
- UnlinkedVariable v = serializeVariableText('final v = 0;');
- checkLinkedTypeSlot(v.propagatedTypeSlot, 'dart:core', 'dart:core', 'int');
- }
-
- test_variable_propagated_type_new_reference() {
- if (skipFullyLinkedData) {
- return;
- }
- UnlinkedVariable v = serializeVariableText('final v = 0;');
- // Since the propagated type of `v` is `int`, and there are no references
- // to `int` elsewhere in the source file, a new linked reference should
- // have been created for it, with no associated unlinked reference.
- expect(v.propagatedTypeSlot, isNot(0));
- EntityRef type = getTypeRefForSlot(v.propagatedTypeSlot);
- expect(type, isNotNull);
- expect(type.reference,
- greaterThanOrEqualTo(unlinkedUnits[0].references.length));
- }
-
- test_variable_propagated_type_omit_dynamic() {
- if (skipFullyLinkedData) {
- return;
- }
- UnlinkedVariable v = serializeVariableText('final v = <int, dynamic>{};');
- EntityRef type = getTypeRefForSlot(v.propagatedTypeSlot);
- checkLinkedTypeRef(type, 'dart:core', 'dart:core', 'Map',
- numTypeParameters: 2, numTypeArguments: 2);
- checkLinkedTypeRef(type.typeArguments[0], 'dart:core', 'dart:core', 'int');
- checkLinkedDynamicTypeRef(type.typeArguments[1]);
- }
-
- test_variable_propagatedTypeSlot_const() {
- // Const variables are propagable so they have a nonzero
- // propagatedTypeSlot.
- UnlinkedVariable variable = serializeVariableText('const v = 0;');
- expect(variable.propagatedTypeSlot, isNot(0));
- }
-
- test_variable_propagatedTypeSlot_final() {
- // Final variables are propagable so they have a nonzero
- // propagatedTypeSlot.
- UnlinkedVariable variable = serializeVariableText('final v = 0;');
- expect(variable.propagatedTypeSlot, isNot(0));
- }
-
- test_variable_propagatedTypeSlot_non_propagable() {
- // Non-final non-const variables aren't propagable so they don't have a
- // propagatedTypeSlot.
- UnlinkedVariable variable = serializeVariableText('var v;');
- expect(variable.propagatedTypeSlot, 0);
- }
-
test_variable_static() {
UnlinkedVariable variable =
serializeClassText('class C { static int i; }').fields[0];
diff --git a/pkg/analyzer/test/src/task/dart_test.dart b/pkg/analyzer/test/src/task/dart_test.dart
index c01223c..06b94cd 100644
--- a/pkg/analyzer/test/src/task/dart_test.dart
+++ b/pkg/analyzer/test/src/task/dart_test.dart
@@ -49,7 +49,6 @@
runReflectiveTests(ComputeConstantValueTaskTest);
runReflectiveTests(ComputeInferableStaticVariableDependenciesTaskTest);
runReflectiveTests(ComputeLibraryCycleTaskTest);
- runReflectiveTests(ComputePropagableVariableDependenciesTaskTest);
runReflectiveTests(ContainingLibrariesTaskTest);
runReflectiveTests(DartErrorsTaskTest);
runReflectiveTests(EvaluateUnitConstantsTaskTest);
@@ -64,8 +63,6 @@
runReflectiveTests(LibraryUnitErrorsTaskTest);
runReflectiveTests(ParseDartTaskTest);
runReflectiveTests(PartiallyResolveUnitReferencesTaskTest);
- runReflectiveTests(PropagateVariableTypesInUnitTaskTest);
- runReflectiveTests(PropagateVariableTypeTaskTest);
runReflectiveTests(ReferencedNamesBuilderTest);
runReflectiveTests(ResolveDirectiveElementsTaskTest);
runReflectiveTests(ResolveInstanceFieldsInUnitTaskTest);
@@ -103,8 +100,6 @@
new isInstanceOf<ComputeConstantValueTask>();
isInstanceOf isComputeInferableStaticVariableDependenciesTask =
new isInstanceOf<ComputeInferableStaticVariableDependenciesTask>();
-isInstanceOf isComputePropagableVariableDependenciesTask =
- new isInstanceOf<ComputePropagableVariableDependenciesTask>();
isInstanceOf isContainingLibrariesTask =
new isInstanceOf<ContainingLibrariesTask>();
isInstanceOf isDartErrorsTask = new isInstanceOf<DartErrorsTask>();
@@ -129,10 +124,6 @@
isInstanceOf isParseDartTask = new isInstanceOf<ParseDartTask>();
isInstanceOf isPartiallyResolveUnitReferencesTask =
new isInstanceOf<PartiallyResolveUnitReferencesTask>();
-isInstanceOf isPropagateVariableTypesInUnitTask =
- new isInstanceOf<PropagateVariableTypesInUnitTask>();
-isInstanceOf isPropagateVariableTypeTask =
- new isInstanceOf<PropagateVariableTypeTask>();
isInstanceOf isResolveDirectiveElementsTask =
new isInstanceOf<ResolveDirectiveElementsTask>();
isInstanceOf isResolveLibraryReferencesTask =
@@ -2017,139 +2008,6 @@
}
@reflectiveTest
-class ComputePropagableVariableDependenciesTaskTest
- extends _AbstractDartTaskTest {
- List<VariableElement> getPropagableVariableDependencies(
- Map<ResultDescriptor, dynamic> outputs) {
- return outputs[PROPAGABLE_VARIABLE_DEPENDENCIES] as List<VariableElement>;
- }
-
- test_perform_instanceField() {
- AnalysisTarget source = newSource(
- '/test.dart',
- '''
-class A {
- final a = a1 + a2 + a3 + a4 + B.b1 + B.b2 + B.b3 + B.b4;
- static const a1 = 1;
- final a2 = 2;
- final a3;
- var a4 = 4;
-}
-class B {
- static const b1 = 1;
- static final b2 = 2;
- static final b3;
- static var b4 = 4;
-}
-''');
- LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT7);
- CompilationUnit unit = outputs[RESOLVED_UNIT7];
- FieldElement elementA = AstFinder.getFieldInClassElement(unit, 'A', 'a');
- // compute
- computeResult(elementA, PROPAGABLE_VARIABLE_DEPENDENCIES,
- matcher: isComputePropagableVariableDependenciesTask);
- // verify
- expect(outputs, hasLength(1));
- List<VariableElement> dependencies =
- getPropagableVariableDependencies(outputs);
- expect(
- dependencies,
- unorderedEquals([
- AstFinder.getFieldInClassElement(unit, 'A', 'a1'),
- AstFinder.getFieldInClassElement(unit, 'A', 'a2'),
- AstFinder.getFieldInClassElement(unit, 'B', 'b1'),
- AstFinder.getFieldInClassElement(unit, 'B', 'b2')
- ]));
- }
-
- test_perform_topLevel() {
- AnalysisTarget source = newSource(
- '/test.dart',
- '''
-const a = d1 + d2 + d3 + d4;
-const d1 = 1;
-final d2 = 2;
-final d3;
-var d4 = 4;
-''');
- LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT7);
- CompilationUnit unit = outputs[RESOLVED_UNIT7];
- TopLevelVariableElement elementA =
- AstFinder.getTopLevelVariableElement(unit, 'a');
- // compute
- computeResult(elementA, PROPAGABLE_VARIABLE_DEPENDENCIES,
- matcher: isComputePropagableVariableDependenciesTask);
- // verify
- expect(outputs, hasLength(1));
- List<VariableElement> dependencies =
- getPropagableVariableDependencies(outputs);
- expect(
- dependencies,
- unorderedEquals([
- AstFinder.getTopLevelVariableElement(unit, 'd1'),
- AstFinder.getTopLevelVariableElement(unit, 'd2')
- ]));
- }
-
- test_perform_topLevel_ignoreLocal() {
- AnalysisTarget source = newSource(
- '/test.dart',
- '''
-final a = () {
- const b = 2;
- const c = 3;
- return b + c;
-}() + d;
-final d = 4;
-''');
- LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT7);
- CompilationUnit unit = outputs[RESOLVED_UNIT7];
- TopLevelVariableElement elementA =
- AstFinder.getTopLevelVariableElement(unit, 'a');
- // compute
- computeResult(elementA, PROPAGABLE_VARIABLE_DEPENDENCIES,
- matcher: isComputePropagableVariableDependenciesTask);
- // verify
- expect(outputs, hasLength(1));
- List<VariableElement> dependencies =
- getPropagableVariableDependencies(outputs);
- expect(dependencies,
- unorderedEquals([AstFinder.getTopLevelVariableElement(unit, 'd')]));
- }
-
- test_perform_topLevel_withoutSpaceAfterType() {
- AnalysisTarget source = newSource(
- '/test.dart',
- '''
-const List<int>a=[b, c];
-const b = 1;
-const c = 2;
-''');
- LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT7);
- CompilationUnit unit = outputs[RESOLVED_UNIT7];
- TopLevelVariableElement elementA =
- AstFinder.getTopLevelVariableElement(unit, 'a');
- // compute
- computeResult(elementA, PROPAGABLE_VARIABLE_DEPENDENCIES,
- matcher: isComputePropagableVariableDependenciesTask);
- // verify
- expect(outputs, hasLength(1));
- List<VariableElement> dependencies =
- getPropagableVariableDependencies(outputs);
- expect(
- dependencies,
- unorderedEquals([
- AstFinder.getTopLevelVariableElement(unit, 'b'),
- AstFinder.getTopLevelVariableElement(unit, 'c')
- ]));
- }
-}
-
-@reflectiveTest
class ContainingLibrariesTaskTest extends _AbstractDartTaskTest {
List<Source> getContainingLibraries(Map<ResultDescriptor, dynamic> outputs) {
return outputs[CONTAINING_LIBRARIES] as List<Source>;
@@ -2237,9 +2095,9 @@
class A {}
''');
LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT13);
- expect(outputs[RESOLVED_UNIT13], isNotNull);
- expect(outputs[CREATED_RESOLVED_UNIT13], isTrue);
+ computeResult(target, RESOLVED_UNIT12);
+ expect(outputs[RESOLVED_UNIT12], isNotNull);
+ expect(outputs[CREATED_RESOLVED_UNIT12], isTrue);
}
test_perform() {
@@ -2256,9 +2114,9 @@
const x = const C();
''');
LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT13,
+ computeResult(target, RESOLVED_UNIT12,
matcher: isEvaluateUnitConstantsTask);
- CompilationUnit unit = outputs[RESOLVED_UNIT13];
+ CompilationUnit unit = outputs[RESOLVED_UNIT12];
CompilationUnitElement unitElement = unit.element;
expect(
(unitElement.types[0].constructors[0] as ConstructorElementImpl)
@@ -2765,9 +2623,9 @@
class A {}
''');
LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT11);
- expect(outputs[RESOLVED_UNIT11], isNotNull);
- expect(outputs[CREATED_RESOLVED_UNIT11], isTrue);
+ computeResult(target, RESOLVED_UNIT10);
+ expect(outputs[RESOLVED_UNIT10], isNotNull);
+ expect(outputs[CREATED_RESOLVED_UNIT10], isTrue);
}
void test_perform() {
@@ -2787,9 +2645,9 @@
class Y {}
class Z {}
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11,
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT10,
matcher: isInferInstanceMembersInUnitTask);
- CompilationUnit unit = outputs[RESOLVED_UNIT11];
+ CompilationUnit unit = outputs[RESOLVED_UNIT10];
VariableDeclaration field = AstFinder.getFieldInClass(unit, 'B', 'f');
MethodDeclaration method = AstFinder.getMethodInClass(unit, 'B', 'm');
DartType typeX = AstFinder.getClass(unit, 'X').element.type;
@@ -2821,12 +2679,12 @@
}
''');
computeResult(
- new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT11,
+ new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT10,
matcher: isInferInstanceMembersInUnitTask);
- CompilationUnit firstUnit = outputs[RESOLVED_UNIT11];
+ CompilationUnit firstUnit = outputs[RESOLVED_UNIT10];
computeResult(
- new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT11);
- CompilationUnit secondUnit = outputs[RESOLVED_UNIT11];
+ new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT10);
+ CompilationUnit secondUnit = outputs[RESOLVED_UNIT10];
VariableDeclaration variableA =
AstFinder.getTopLevelVariable(firstUnit, 'a');
@@ -2853,8 +2711,8 @@
String field = topLevel;
}
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
- CompilationUnit unit = outputs[RESOLVED_UNIT11];
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT10);
+ CompilationUnit unit = outputs[RESOLVED_UNIT10];
VariableDeclaration topLevelDecl =
AstFinder.getTopLevelVariable(unit, 'topLevel');
VariableDeclaration fieldDecl =
@@ -2885,9 +2743,9 @@
class A {}
''');
LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT9);
- expect(outputs[RESOLVED_UNIT9], isNotNull);
- expect(outputs[CREATED_RESOLVED_UNIT9], isTrue);
+ computeResult(target, RESOLVED_UNIT8);
+ expect(outputs[RESOLVED_UNIT8], isNotNull);
+ expect(outputs[CREATED_RESOLVED_UNIT8], isTrue);
}
void test_perform_const_field() {
@@ -2899,9 +2757,9 @@
static const X = "";
}
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9,
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8,
matcher: isInferStaticVariableTypesInUnitTask);
- CompilationUnit unit = outputs[RESOLVED_UNIT9];
+ CompilationUnit unit = outputs[RESOLVED_UNIT8];
VariableDeclaration declaration = AstFinder.getFieldInClass(unit, 'M', 'X');
InterfaceType stringType = context.typeProvider.stringType;
expect(declaration.element.type, stringType);
@@ -2914,9 +2772,9 @@
@(i $=
''');
LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT9);
- expect(outputs[RESOLVED_UNIT9], isNotNull);
- expect(outputs[CREATED_RESOLVED_UNIT9], isTrue);
+ computeResult(target, RESOLVED_UNIT8);
+ expect(outputs[RESOLVED_UNIT8], isNotNull);
+ expect(outputs[CREATED_RESOLVED_UNIT8], isTrue);
}
void test_perform_nestedDeclarations() {
@@ -2930,7 +2788,7 @@
return xSquared;
};
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9,
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8,
matcher: isInferStaticVariableTypesInUnitTask);
}
@@ -2953,12 +2811,12 @@
class M {}
''');
computeResult(
- new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT9,
+ new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT8,
matcher: isInferStaticVariableTypesInUnitTask);
- CompilationUnit firstUnit = outputs[RESOLVED_UNIT9];
+ CompilationUnit firstUnit = outputs[RESOLVED_UNIT8];
computeResult(
- new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT9);
- CompilationUnit secondUnit = outputs[RESOLVED_UNIT9];
+ new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT8);
+ CompilationUnit secondUnit = outputs[RESOLVED_UNIT8];
VariableDeclaration variableA =
AstFinder.getTopLevelVariable(firstUnit, 'a');
@@ -2987,9 +2845,9 @@
return 1 + X;
};
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9,
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8,
matcher: isInferStaticVariableTypesInUnitTask);
- CompilationUnit unit = outputs[RESOLVED_UNIT9];
+ CompilationUnit unit = outputs[RESOLVED_UNIT8];
TopLevelVariableDeclaration declaration = unit.declarations[1];
FunctionExpression function =
declaration.variables.variables[0].initializer;
@@ -3010,9 +2868,9 @@
var V = [42];
''');
LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT9);
- expect(outputs[RESOLVED_UNIT9], isNotNull);
- expect(outputs[CREATED_RESOLVED_UNIT9], isTrue);
+ computeResult(target, RESOLVED_UNIT8);
+ expect(outputs[RESOLVED_UNIT8], isNotNull);
+ expect(outputs[CREATED_RESOLVED_UNIT8], isTrue);
// An INFERRED_TYPE_LITERAL error should be generated.
List<AnalysisError> errors = outputs[
STATIC_VARIABLE_RESOLUTION_ERRORS_IN_UNIT] as List<AnalysisError>;
@@ -3425,36 +3283,6 @@
@reflectiveTest
class PartiallyResolveUnitReferencesTaskTest extends _AbstractDartTaskTest {
- test_perform_propagable() {
- enableStrongMode();
- Source source = newSource(
- '/test.dart',
- '''
-const t1 = 1;
-final t2 = 2;
-var t3 = 3;
-final t4;
-class C {
- static const fs1 = 1;
- static final fs2 = 2;
- static var fs3 = 3;
- static final fs4;
- const fi1 = 1;
- final fi2 = 2;
- var fi3 = 3;
- final fi4;
-}
-''');
- LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, PROPAGABLE_VARIABLES_IN_UNIT,
- matcher: isPartiallyResolveUnitReferencesTask);
- // PROPAGABLE_VARIABLES_IN_UNIT
- List<VariableElement> variables =
- outputs[PROPAGABLE_VARIABLES_IN_UNIT] as List<VariableElement>;
- expect(variables.map((v) => v.displayName),
- unorderedEquals(['t1', 't2', 'fs1', 'fs2', 'fi1', 'fi2']));
- }
-
test_perform_strong_importExport() {
newSource(
'/a.dart',
@@ -3597,138 +3425,6 @@
}
@reflectiveTest
-class PropagateVariableTypesInUnitTaskTest extends _AbstractDartTaskTest {
- test_created_resolved_unit() {
- Source source = newSource(
- '/test.dart',
- r'''
-library lib;
-class A {}
-''');
- LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT8);
- expect(outputs[RESOLVED_UNIT8], isNotNull);
- expect(outputs[CREATED_RESOLVED_UNIT8], isTrue);
- }
-
- void test_perform_cycle() {
- AnalysisTarget source = newSource(
- '/test.dart',
- '''
-final piFirst = true;
-final pi = piFirst ? 3.14 : tau / 2;
-final tau = piFirst ? pi * 2 : 6.28;
-''');
- // compute
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8,
- matcher: isPropagateVariableTypesInUnitTask);
- CompilationUnit unit = outputs[RESOLVED_UNIT8];
- // verify
- TopLevelVariableElement piFirst =
- AstFinder.getTopLevelVariableElement(unit, 'piFirst');
- TopLevelVariableElement pi =
- AstFinder.getTopLevelVariableElement(unit, 'pi');
- TopLevelVariableElement tau =
- AstFinder.getTopLevelVariableElement(unit, 'tau');
- expect(piFirst.propagatedType, context.typeProvider.boolType);
- expect(pi.propagatedType, isNull);
- expect(tau.propagatedType, isNull);
- }
-
- void test_perform_topLevel() {
- AnalysisTarget source = newSource(
- '/test.dart',
- '''
-//final a = b + c.length;
-final a = b;
-final b = 1;
-final c = '2';
-''');
- // compute
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8,
- matcher: isPropagateVariableTypesInUnitTask);
- CompilationUnit unit = outputs[RESOLVED_UNIT8];
- // verify
- InterfaceType intType = context.typeProvider.intType;
- InterfaceType stringType = context.typeProvider.stringType;
- expect(AstFinder.getTopLevelVariableElement(unit, 'a').propagatedType,
- intType);
- expect(AstFinder.getTopLevelVariableElement(unit, 'b').propagatedType,
- intType);
- expect(AstFinder.getTopLevelVariableElement(unit, 'c').propagatedType,
- stringType);
- }
-}
-
-@reflectiveTest
-class PropagateVariableTypeTaskTest extends _AbstractDartTaskTest {
- void test_perform_cycle() {
- AnalysisTarget source = newSource(
- '/test.dart',
- '''
-final piFirst = true;
-final pi = piFirst ? 3.14 : tau / 2;
-final tau = piFirst ? pi * 2 : 6.28;
-''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
- CompilationUnit unit = outputs[RESOLVED_UNIT7];
- TopLevelVariableElement piFirst =
- AstFinder.getTopLevelVariableElement(unit, 'piFirst');
- TopLevelVariableElement pi =
- AstFinder.getTopLevelVariableElement(unit, 'pi');
- TopLevelVariableElement tau =
- AstFinder.getTopLevelVariableElement(unit, 'tau');
- // compute
- computeResult(piFirst, PROPAGATED_VARIABLE,
- matcher: isPropagateVariableTypeTask);
- expect(piFirst.propagatedType, context.typeProvider.boolType);
- expect(pi.propagatedType, isNull);
- expect(tau.propagatedType, isNull);
- }
-
- void test_perform_null() {
- enableStrongMode();
- AnalysisTarget source = newSource(
- '/test.dart',
- '''
-var a = null;
-''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
- CompilationUnit unit = outputs[RESOLVED_UNIT7];
- TopLevelVariableElement a = AstFinder.getTopLevelVariableElement(unit, 'a');
- // compute
- computeResult(a, PROPAGATED_VARIABLE, matcher: isPropagateVariableTypeTask);
- expect(a.propagatedType, isNull);
- }
-
- void test_perform_topLevel() {
- AnalysisTarget source = newSource(
- '/test.dart',
- '''
-final a = b + c.length;
-final b = 1;
-final c = '2';
-''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
- CompilationUnit unit = outputs[RESOLVED_UNIT7];
- TopLevelVariableElement elementA =
- AstFinder.getTopLevelVariableElement(unit, 'a');
- TopLevelVariableElement elementB =
- AstFinder.getTopLevelVariableElement(unit, 'b');
- TopLevelVariableElement elementC =
- AstFinder.getTopLevelVariableElement(unit, 'c');
- // compute
- computeResult(elementA, PROPAGATED_VARIABLE,
- matcher: isPropagateVariableTypeTask);
- InterfaceType intType = context.typeProvider.intType;
- InterfaceType stringType = context.typeProvider.stringType;
- expect(elementA.propagatedType, intType);
- expect(elementB.propagatedType, intType);
- expect(elementC.propagatedType, stringType);
- }
-}
-
-@reflectiveTest
class ReferencedNamesBuilderTest extends _AbstractDartTaskTest {
void setUp() {
super.setUp();
@@ -4257,9 +3953,9 @@
class A {}
''');
LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT10);
- expect(outputs[RESOLVED_UNIT10], isNotNull);
- expect(outputs[CREATED_RESOLVED_UNIT10], isTrue);
+ computeResult(target, RESOLVED_UNIT9);
+ expect(outputs[RESOLVED_UNIT9], isNotNull);
+ expect(outputs[CREATED_RESOLVED_UNIT9], isTrue);
}
// Test inference of instance fields across units
@@ -4289,16 +3985,16 @@
DartType dynamicType = context.typeProvider.dynamicType;
computeResult(
- new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT10);
- CompilationUnit unit1 = outputs[RESOLVED_UNIT10];
+ new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT9);
+ CompilationUnit unit1 = outputs[RESOLVED_UNIT9];
// B.b2 shoud be resolved on the rhs, but not yet inferred.
assertVariableDeclarationTypes(
AstFinder.getFieldInClass(unit1, "B", "b2"), dynamicType, intType);
computeResult(
- new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT10);
- CompilationUnit unit0 = outputs[RESOLVED_UNIT10];
+ new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT9);
+ CompilationUnit unit0 = outputs[RESOLVED_UNIT9];
// B.b2 should now be fully resolved and inferred.
assertVariableDeclarationTypes(
@@ -4309,7 +4005,7 @@
AstFinder.getFieldInClass(unit0, "A", "a2"), dynamicType, intType);
computeResult(
- new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT10);
+ new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT9);
// A.a2 should now be fully resolved and inferred.
assertVariableDeclarationTypes(
@@ -4346,15 +4042,15 @@
DartType dynamicType = context.typeProvider.dynamicType;
computeResult(
- new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT10);
- CompilationUnit unit0 = outputs[RESOLVED_UNIT10];
+ new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT9);
+ CompilationUnit unit0 = outputs[RESOLVED_UNIT9];
// A.a2 should now be resolved on the rhs, but not yet inferred.
assertVariableDeclarationTypes(
AstFinder.getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType);
computeResult(
- new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT10);
+ new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT9);
// A.a2 should now be fully resolved and inferred (but not re-resolved).
assertVariableDeclarationTypes(
@@ -4392,8 +4088,8 @@
DartType dynamicType = context.typeProvider.dynamicType;
computeResult(
- new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT10);
- CompilationUnit unit1 = outputs[RESOLVED_UNIT10];
+ new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT9);
+ CompilationUnit unit1 = outputs[RESOLVED_UNIT9];
assertVariableDeclarationTypes(
AstFinder.getFieldInClass(unit1, "B", "b1"), intType, intType);
@@ -4401,8 +4097,8 @@
AstFinder.getFieldInClass(unit1, "B", "b2"), dynamicType, intType);
computeResult(
- new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT10);
- CompilationUnit unit0 = outputs[RESOLVED_UNIT10];
+ new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT9);
+ CompilationUnit unit0 = outputs[RESOLVED_UNIT9];
assertVariableDeclarationTypes(
AstFinder.getFieldInClass(unit0, "A", "a1"), intType, intType);
@@ -4415,7 +4111,7 @@
AstFinder.getFieldInClass(unit1, "B", "b2"), intType, intType);
computeResult(
- new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT10);
+ new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT9);
assertVariableDeclarationTypes(
AstFinder.getFieldInClass(unit0, "A", "a1"), intType, intType);
@@ -4454,8 +4150,8 @@
DartType dynamicType = context.typeProvider.dynamicType;
computeResult(
- new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT10);
- CompilationUnit unit0 = outputs[RESOLVED_UNIT10];
+ new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT9);
+ CompilationUnit unit0 = outputs[RESOLVED_UNIT9];
// A.a2 should now be resolved on the rhs, but not yet inferred.
assertVariableDeclarationTypes(
@@ -4466,7 +4162,7 @@
AstFinder.getFieldInClass(unit0, "B", "b2"), dynamicType, intType);
computeResult(
- new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT10);
+ new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT9);
// A.a2 should now be fully resolved and inferred (but not re-resolved).
assertVariableDeclarationTypes(
@@ -4703,9 +4399,9 @@
class A {}
''');
LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT12);
- expect(outputs[RESOLVED_UNIT12], isNotNull);
- expect(outputs[CREATED_RESOLVED_UNIT12], isTrue);
+ computeResult(target, RESOLVED_UNIT11);
+ expect(outputs[RESOLVED_UNIT11], isNotNull);
+ expect(outputs[CREATED_RESOLVED_UNIT11], isTrue);
}
void test_perform() {
@@ -4722,9 +4418,9 @@
}
}
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT12,
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11,
matcher: isResolveUnitTask);
- CompilationUnit unit = outputs[RESOLVED_UNIT12];
+ CompilationUnit unit = outputs[RESOLVED_UNIT11];
FunctionDeclaration f = unit.declarations[0];
_assertResolved(f.functionExpression.body);
@@ -4735,33 +4431,6 @@
expect(outputs[RESOLVE_UNIT_ERRORS], hasLength(0));
}
- void test_perform_ensurePropagatedVariableTypes() {
- newSource(
- '/lib.dart',
- '''
-class A {
- final v = 1;
-}
-''');
- AnalysisTarget source = newSource(
- '/test.dart',
- '''
-import 'lib.dart';
-main(A a) {
- a.v.isEven;
-}
-''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT12,
- matcher: isResolveUnitTask);
- expect(outputs[RESOLVE_UNIT_ERRORS], hasLength(0));
- CompilationUnit unit = outputs[RESOLVED_UNIT12];
- FunctionDeclaration main = unit.declarations[0];
- BlockFunctionBody body = main.functionExpression.body;
- ExpressionStatement statement = body.block.statements.single;
- Expression expression = statement.expression;
- expect(expression.bestType, context.typeProvider.boolType);
- }
-
void _assertResolved(FunctionBody body) {
ResolutionVerifier verifier = new ResolutionVerifier();
body.accept(verifier);
@@ -5056,8 +4725,8 @@
var pi = piFirst ? 3.14 : tau / 2;
var tau = piFirst ? pi * 2 : 6.28;
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT12);
- CompilationUnit unit = outputs[RESOLVED_UNIT12];
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
+ CompilationUnit unit = outputs[RESOLVED_UNIT11];
VariableElement piFirst =
AstFinder.getTopLevelVariable(unit, 'piFirst').name.staticElement;
VariableElement pi =
@@ -5099,11 +4768,11 @@
}
''');
computeResult(
- new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT12);
- CompilationUnit unit1 = outputs[RESOLVED_UNIT12];
+ new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT11);
+ CompilationUnit unit1 = outputs[RESOLVED_UNIT11];
computeResult(
- new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT12);
- CompilationUnit unit2 = outputs[RESOLVED_UNIT12];
+ new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT11);
+ CompilationUnit unit2 = outputs[RESOLVED_UNIT11];
InterfaceType intType = context.typeProvider.intType;
@@ -5150,7 +4819,7 @@
'''
});
List<dynamic> units =
- computeLibraryResults(sources, RESOLVED_UNIT12).toList();
+ computeLibraryResults(sources, RESOLVED_UNIT11).toList();
CompilationUnit unit0 = units[0];
CompilationUnit unit1 = units[1];
CompilationUnit unit2 = units[2];
@@ -5197,7 +4866,7 @@
'''
});
List<dynamic> units =
- computeLibraryResults(sources, RESOLVED_UNIT12).toList();
+ computeLibraryResults(sources, RESOLVED_UNIT11).toList();
CompilationUnit unit0 = units[0];
CompilationUnit unit2 = units[2];
@@ -5238,11 +4907,11 @@
}
''');
computeResult(
- new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT12);
- CompilationUnit unit1 = outputs[RESOLVED_UNIT12];
+ new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT11);
+ CompilationUnit unit1 = outputs[RESOLVED_UNIT11];
computeResult(
- new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT12);
- CompilationUnit unit2 = outputs[RESOLVED_UNIT12];
+ new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT11);
+ CompilationUnit unit2 = outputs[RESOLVED_UNIT11];
InterfaceType intType = context.typeProvider.intType;
InterfaceType stringType = context.typeProvider.stringType;
@@ -5292,7 +4961,7 @@
'''
});
List<dynamic> units =
- computeLibraryResults(sources, RESOLVED_UNIT12).toList();
+ computeLibraryResults(sources, RESOLVED_UNIT11).toList();
CompilationUnit unit0 = units[0];
CompilationUnit unit1 = units[1];
CompilationUnit unit2 = units[2];
@@ -5328,8 +4997,8 @@
y = "hi";
}
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT12);
- CompilationUnit unit = outputs[RESOLVED_UNIT12];
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
+ CompilationUnit unit = outputs[RESOLVED_UNIT11];
InterfaceType intType = context.typeProvider.intType;
InterfaceType stringType = context.typeProvider.stringType;
@@ -5367,8 +5036,8 @@
final z = 42; // should infer `int`
}
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT12);
- CompilationUnit unit = outputs[RESOLVED_UNIT12];
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
+ CompilationUnit unit = outputs[RESOLVED_UNIT11];
InterfaceType intType = context.typeProvider.intType;
InterfaceType stringType = context.typeProvider.stringType;
@@ -5416,8 +5085,8 @@
int y = 0; // field def after use
final z = 42; // should infer `int`
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT12);
- CompilationUnit unit = outputs[RESOLVED_UNIT12];
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
+ CompilationUnit unit = outputs[RESOLVED_UNIT11];
InterfaceType intType = context.typeProvider.intType;
InterfaceType stringType = context.typeProvider.stringType;
@@ -5469,8 +5138,8 @@
new A().y2 = /*severe:StaticTypeError*/"hi";
}
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT12);
- CompilationUnit unit = outputs[RESOLVED_UNIT12];
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
+ CompilationUnit unit = outputs[RESOLVED_UNIT11];
InterfaceType intType = context.typeProvider.intType;
InterfaceType stringType = context.typeProvider.stringType;
@@ -5511,8 +5180,8 @@
x = "hi";
}
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT12);
- CompilationUnit unit = outputs[RESOLVED_UNIT12];
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
+ CompilationUnit unit = outputs[RESOLVED_UNIT11];
InterfaceType intType = context.typeProvider.intType;
InterfaceType stringType = context.typeProvider.stringType;
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index a00747e..4c2d8af 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -269,7 +269,7 @@
test() {
int x = 0;
x += 5;
- x += /*error:INVALID_ASSIGNMENT*/3.14;
+ /*error:STATIC_TYPE_ERROR*/x += /*error:INVALID_ASSIGNMENT*/3.14;
double y = 0.0;
y += 5;
@@ -280,12 +280,12 @@
z += 3.14;
x = /*info:DOWN_CAST_IMPLICIT*/x + z;
- /*info:DOWN_CAST_IMPLICIT*/x += z;
+ x += /*info:DOWN_CAST_IMPLICIT*/z;
y = y + z;
y += z;
dynamic w = 42;
- /*info:DOWN_CAST_IMPLICIT*/x += /*info:DYNAMIC_CAST*/w;
+ x += /*info:DYNAMIC_CAST*/w;
y += /*info:DYNAMIC_CAST*/w;
z += /*info:DYNAMIC_CAST*/w;
@@ -301,7 +301,7 @@
a += b;
a += /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/a;
a -= b;
- b -= /*error:INVALID_ASSIGNMENT*/b;
+ /*error:STATIC_TYPE_ERROR*/b -= /*error:INVALID_ASSIGNMENT*/b;
a <<= b;
a >>= b;
a &= b;
@@ -320,20 +320,6 @@
''');
}
- void test_compoundAssignment_returnsDynamic() {
- checkFile(r'''
-class Foo {
- operator +(other) => null;
-}
-
-main() {
- var foo = new Foo();
- foo = /*info:DYNAMIC_CAST*/foo + 1;
- /*info:DYNAMIC_CAST*/foo += 1;
-}
- ''');
- }
-
void test_constructorInvalid() {
// Regression test for https://github.com/dart-lang/sdk/issues/26695
checkFile('''
diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
index 8b00a44..0087b3d 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -1609,6 +1609,17 @@
''');
}
+ void test_futureThen_explicitFuture() {
+ checkFile(r'''
+import "dart:async";
+main() {
+ Future<int> f;
+ var x = f.then/*<Future<List<int>>>*/(/*info:INFERRED_TYPE_CLOSURE*/(x) => /*info:INFERRED_TYPE_LITERAL*/[]);
+ Future<List<int>> y = x;
+}
+ ''');
+ }
+
void test_futureThen_upwards() {
// Regression test for https://github.com/dart-lang/sdk/issues/27088.
String build({String declared, String downwards, String upwards}) => '''
@@ -1676,24 +1687,6 @@
checkFile(build(downwards: "Future", upwards: "MyFuture"));
}
- void test_futureUnion_downwardsGenericMethods() {
- // Regression test for https://github.com/dart-lang/sdk/issues/27134
- //
- // We need to take a future union into account for both directions of
- // generic method inference.
- checkFile(r'''
-import 'dart:async';
-
-foo() async {
- Future<List<A>> f1 = null;
- Future<List<A>> f2 = null;
- List<List<A>> merged = await Future.wait(/*info:INFERRED_TYPE_LITERAL*/[f1, f2]);
-}
-
-class A {}
- ''');
- }
-
void test_futureUnion_downwards() {
String build({String declared, String downwards, String upwards}) {
// TODO(leafp): The use of matchTypes in visitInstanceCreationExpression
@@ -1736,6 +1729,24 @@
build(declared: "Future", downwards: "Future", upwards: "MyFuture"));
}
+ void test_futureUnion_downwardsGenericMethods() {
+ // Regression test for https://github.com/dart-lang/sdk/issues/27134
+ //
+ // We need to take a future union into account for both directions of
+ // generic method inference.
+ checkFile(r'''
+import 'dart:async';
+
+foo() async {
+ Future<List<A>> f1 = null;
+ Future<List<A>> f2 = null;
+ List<List<A>> merged = await Future.wait(/*info:INFERRED_TYPE_LITERAL*/[f1, f2]);
+}
+
+class A {}
+ ''');
+ }
+
void test_genericMethods_basicDownwardInference() {
checkFile(r'''
/*=T*/ f/*<S, T>*/(/*=S*/ s) => null;
diff --git a/pkg/analyzer/tool/task_dependency_graph/tasks.dot b/pkg/analyzer/tool/task_dependency_graph/tasks.dot
index 7cf3d9d..e6af229 100644
--- a/pkg/analyzer/tool/task_dependency_graph/tasks.dot
+++ b/pkg/analyzer/tool/task_dependency_graph/tasks.dot
@@ -48,24 +48,23 @@
CREATED_RESOLVED_UNIT [shape=box]
CREATED_RESOLVED_UNIT1 [shape=box]
CREATED_RESOLVED_UNIT10 -> InferInstanceMembersInUnitTask
+ CREATED_RESOLVED_UNIT10 -> InferStaticVariableTypeTask
+ CREATED_RESOLVED_UNIT10 -> PartiallyResolveUnitReferencesTask
+ CREATED_RESOLVED_UNIT10 -> ResolveInstanceFieldsInUnitTask
+ CREATED_RESOLVED_UNIT10 -> ResolveUnitTask
CREATED_RESOLVED_UNIT10 [shape=box]
- CREATED_RESOLVED_UNIT11 -> InferInstanceMembersInUnitTask
- CREATED_RESOLVED_UNIT11 -> InferStaticVariableTypeTask
- CREATED_RESOLVED_UNIT11 -> PartiallyResolveUnitReferencesTask
- CREATED_RESOLVED_UNIT11 -> ResolveInstanceFieldsInUnitTask
- CREATED_RESOLVED_UNIT11 -> ResolveUnitTask
+ CREATED_RESOLVED_UNIT11 -> ResolveConstantExpressionTask
CREATED_RESOLVED_UNIT11 [shape=box]
- CREATED_RESOLVED_UNIT12 -> ResolveConstantExpressionTask
CREATED_RESOLVED_UNIT12 [shape=box]
- CREATED_RESOLVED_UNIT13 [shape=box]
CREATED_RESOLVED_UNIT2 [shape=box]
CREATED_RESOLVED_UNIT3 [shape=box]
CREATED_RESOLVED_UNIT4 [shape=box]
CREATED_RESOLVED_UNIT5 [shape=box]
CREATED_RESOLVED_UNIT6 [shape=box]
CREATED_RESOLVED_UNIT7 [shape=box]
+ CREATED_RESOLVED_UNIT8 -> ResolveInstanceFieldsInUnitTask
CREATED_RESOLVED_UNIT8 [shape=box]
- CREATED_RESOLVED_UNIT9 -> ResolveInstanceFieldsInUnitTask
+ CREATED_RESOLVED_UNIT9 -> InferInstanceMembersInUnitTask
CREATED_RESOLVED_UNIT9 [shape=box]
ComputeConstantDependenciesTask -> CONSTANT_DEPENDENCIES
ComputeConstantValueTask -> CONSTANT_VALUE
@@ -73,7 +72,6 @@
ComputeLibraryCycleTask -> LIBRARY_CYCLE
ComputeLibraryCycleTask -> LIBRARY_CYCLE_DEPENDENCIES
ComputeLibraryCycleTask -> LIBRARY_CYCLE_UNITS
- ComputePropagableVariableDependenciesTask -> PROPAGABLE_VARIABLE_DEPENDENCIES
ComputeRequiredConstantsTask -> PENDING_ERRORS
ComputeRequiredConstantsTask -> REQUIRED_CONSTANTS
ContainingLibrariesTask -> CONTAINING_LIBRARIES
@@ -86,14 +84,14 @@
EXPORTED_LIBRARIES -> BuildDirectiveElementsTask
EXPORTED_LIBRARIES -> ReadyLibraryElement2Task
EXPORTED_LIBRARIES -> ReadyLibraryElement5Task
- EXPORTED_LIBRARIES -> ReadyLibraryElement6Task
+ EXPORTED_LIBRARIES -> ReadyLibraryElement7Task
EXPORTED_LIBRARIES -> ResolveTopLevelLibraryTypeBoundsTask
EXPORTED_LIBRARIES [shape=box]
EXPORT_SOURCE_CLOSURE -> BuildExportNamespaceTask
EXPORT_SOURCE_CLOSURE -> ResolveTopLevelUnitTypeBoundsTask
EXPORT_SOURCE_CLOSURE [shape=box]
- EvaluateUnitConstantsTask -> CREATED_RESOLVED_UNIT13
- EvaluateUnitConstantsTask -> RESOLVED_UNIT13
+ EvaluateUnitConstantsTask -> CREATED_RESOLVED_UNIT12
+ EvaluateUnitConstantsTask -> RESOLVED_UNIT12
GatherUsedImportedElementsTask -> USED_IMPORTED_ELEMENTS
GatherUsedLocalElementsTask -> USED_LOCAL_ELEMENTS
GenerateHintsTask -> HINTS
@@ -105,7 +103,7 @@
IMPORTED_LIBRARIES -> BuildDirectiveElementsTask
IMPORTED_LIBRARIES -> ReadyLibraryElement2Task
IMPORTED_LIBRARIES -> ReadyLibraryElement5Task
- IMPORTED_LIBRARIES -> ReadyLibraryElement6Task
+ IMPORTED_LIBRARIES -> ReadyLibraryElement7Task
IMPORTED_LIBRARIES -> ResolveTopLevelLibraryTypeBoundsTask
IMPORTED_LIBRARIES -> ResolveTopLevelUnitTypeBoundsTask
IMPORTED_LIBRARIES [shape=box]
@@ -119,12 +117,12 @@
INFERRED_STATIC_VARIABLE -> InferStaticVariableTypesInUnitTask
INFERRED_STATIC_VARIABLE [shape=box]
IS_LAUNCHABLE [shape=box]
- InferInstanceMembersInUnitTask -> CREATED_RESOLVED_UNIT11
- InferInstanceMembersInUnitTask -> RESOLVED_UNIT11
+ InferInstanceMembersInUnitTask -> CREATED_RESOLVED_UNIT10
+ InferInstanceMembersInUnitTask -> RESOLVED_UNIT10
InferStaticVariableTypeTask -> INFERRED_STATIC_VARIABLE
InferStaticVariableTypeTask -> STATIC_VARIABLE_RESOLUTION_ERRORS
- InferStaticVariableTypesInUnitTask -> CREATED_RESOLVED_UNIT9
- InferStaticVariableTypesInUnitTask -> RESOLVED_UNIT9
+ InferStaticVariableTypesInUnitTask -> CREATED_RESOLVED_UNIT8
+ InferStaticVariableTypesInUnitTask -> RESOLVED_UNIT8
InferStaticVariableTypesInUnitTask -> STATIC_VARIABLE_RESOLUTION_ERRORS_IN_UNIT
LIBRARY_CYCLE [shape=box]
LIBRARY_CYCLE_DEPENDENCIES -> InferInstanceMembersInUnitTask
@@ -158,12 +156,12 @@
LIBRARY_ELEMENT5 -> ResolveUnitTypeNamesTask
LIBRARY_ELEMENT5 [shape=box]
LIBRARY_ELEMENT6 -> PartiallyResolveUnitReferencesTask
- LIBRARY_ELEMENT6 -> PropagateVariableTypesInLibraryTask
LIBRARY_ELEMENT6 -> ReadyLibraryElement5Task
LIBRARY_ELEMENT6 -> ResolveInstanceFieldsInUnitTask
+ LIBRARY_ELEMENT6 -> ResolvedUnit7InLibraryTask
LIBRARY_ELEMENT6 [shape=box]
- LIBRARY_ELEMENT7 -> PropagateVariableTypesInLibraryClosureTask
- LIBRARY_ELEMENT7 -> ReadyLibraryElement6Task
+ LIBRARY_ELEMENT7 -> ReadyLibraryElement7Task
+ LIBRARY_ELEMENT7 -> ResolvedUnit7InLibraryClosureTask
LIBRARY_ELEMENT7 [shape=box]
LIBRARY_ELEMENT8 -> ResolveLibraryReferencesTask
LIBRARY_ELEMENT8 -> ResolveUnitTask
@@ -173,11 +171,11 @@
LIBRARY_ELEMENT9 [shape=box]
LIBRARY_ERRORS_READY [shape=box]
LIBRARY_SPECIFIC_UNITS -> GenerateHintsTask
- LIBRARY_SPECIFIC_UNITS -> PropagateVariableTypesInLibraryTask
LIBRARY_SPECIFIC_UNITS -> ReadyResolvedUnitTask
LIBRARY_SPECIFIC_UNITS -> ResolveLibraryReferencesTask
LIBRARY_SPECIFIC_UNITS -> ResolveLibraryTypeNamesTask
LIBRARY_SPECIFIC_UNITS -> ResolveTopLevelLibraryTypeBoundsTask
+ LIBRARY_SPECIFIC_UNITS -> ResolvedUnit7InLibraryTask
LIBRARY_SPECIFIC_UNITS [shape=box]
LIBRARY_UNIT_ERRORS -> dartErrorsForUnit
LIBRARY_UNIT_ERRORS [shape=box]
@@ -200,13 +198,6 @@
PARSE_ERRORS [shape=box]
PENDING_ERRORS -> VerifyUnitTask
PENDING_ERRORS [shape=box]
- PROPAGABLE_VARIABLES_IN_UNIT -> PropagateVariableTypesInUnitTask
- PROPAGABLE_VARIABLES_IN_UNIT [shape=box]
- PROPAGABLE_VARIABLE_DEPENDENCIES -> PropagateVariableTypeTask
- PROPAGABLE_VARIABLE_DEPENDENCIES [shape=box]
- PROPAGATED_VARIABLE -> PropagateVariableTypeTask
- PROPAGATED_VARIABLE -> PropagateVariableTypesInUnitTask
- PROPAGATED_VARIABLE [shape=box]
ParseDartTask -> EXPLICITLY_IMPORTED_LIBRARIES
ParseDartTask -> EXPORTED_LIBRARIES
ParseDartTask -> IMPORTED_LIBRARIES
@@ -220,21 +211,15 @@
ParseDartTask -> UNITS
PartiallyResolveUnitReferencesTask -> CREATED_RESOLVED_UNIT7
PartiallyResolveUnitReferencesTask -> INFERABLE_STATIC_VARIABLES_IN_UNIT
- PartiallyResolveUnitReferencesTask -> PROPAGABLE_VARIABLES_IN_UNIT
PartiallyResolveUnitReferencesTask -> RESOLVED_UNIT7
- PropagateVariableTypeTask -> PROPAGATED_VARIABLE
- PropagateVariableTypesInLibraryClosureTask -> LIBRARY_ELEMENT8
- PropagateVariableTypesInLibraryTask -> LIBRARY_ELEMENT7
- PropagateVariableTypesInUnitTask -> CREATED_RESOLVED_UNIT8
- PropagateVariableTypesInUnitTask -> RESOLVED_UNIT8
READY_LIBRARY_ELEMENT2 -> ComputeLibraryCycleTask
READY_LIBRARY_ELEMENT2 -> ReadyLibraryElement2Task
READY_LIBRARY_ELEMENT2 [shape=box]
READY_LIBRARY_ELEMENT6 -> PartiallyResolveUnitReferencesTask
READY_LIBRARY_ELEMENT6 -> ReadyLibraryElement5Task
READY_LIBRARY_ELEMENT6 [shape=box]
- READY_LIBRARY_ELEMENT7 -> PropagateVariableTypesInLibraryClosureTask
- READY_LIBRARY_ELEMENT7 -> ReadyLibraryElement6Task
+ READY_LIBRARY_ELEMENT7 -> ReadyLibraryElement7Task
+ READY_LIBRARY_ELEMENT7 -> ResolvedUnit7InLibraryClosureTask
READY_LIBRARY_ELEMENT7 [shape=box]
READY_RESOLVED_UNIT -> ResolveLibraryTask
READY_RESOLVED_UNIT -> VerifyUnitTask
@@ -255,17 +240,15 @@
RESOLVED_UNIT1 -> BuildLibraryElementTask
RESOLVED_UNIT1 -> ResolveDirectiveElementsTask
RESOLVED_UNIT1 [shape=box]
- RESOLVED_UNIT10 -> InferInstanceMembersInUnitTask
+ RESOLVED_UNIT10 -> ResolveUnitTask
RESOLVED_UNIT10 [shape=box]
- RESOLVED_UNIT11 -> ResolveUnitTask
+ RESOLVED_UNIT11 -> EvaluateUnitConstantsTask
+ RESOLVED_UNIT11 -> GatherUsedImportedElementsTask
+ RESOLVED_UNIT11 -> GatherUsedLocalElementsTask
+ RESOLVED_UNIT11 -> ResolveLibraryReferencesTask
RESOLVED_UNIT11 [shape=box]
- RESOLVED_UNIT12 -> EvaluateUnitConstantsTask
- RESOLVED_UNIT12 -> GatherUsedImportedElementsTask
- RESOLVED_UNIT12 -> GatherUsedLocalElementsTask
- RESOLVED_UNIT12 -> ResolveLibraryReferencesTask
+ RESOLVED_UNIT12 -> StrongModeVerifyUnitTask
RESOLVED_UNIT12 [shape=box]
- RESOLVED_UNIT13 -> StrongModeVerifyUnitTask
- RESOLVED_UNIT13 [shape=box]
RESOLVED_UNIT2 -> BuildEnumMemberElementsTask
RESOLVED_UNIT2 [shape=box]
RESOLVED_UNIT3 -> ResolveTopLevelUnitTypeBoundsTask
@@ -279,15 +262,13 @@
RESOLVED_UNIT6 -> PartiallyResolveUnitReferencesTask
RESOLVED_UNIT6 [shape=box]
RESOLVED_UNIT7 -> ComputeInferableStaticVariableDependenciesTask
- RESOLVED_UNIT7 -> ComputePropagableVariableDependenciesTask
- RESOLVED_UNIT7 -> PropagateVariableTypeTask
- RESOLVED_UNIT7 -> PropagateVariableTypesInUnitTask
+ RESOLVED_UNIT7 -> InferStaticVariableTypeTask
+ RESOLVED_UNIT7 -> InferStaticVariableTypesInUnitTask
+ RESOLVED_UNIT7 -> ResolvedUnit7InLibraryTask
RESOLVED_UNIT7 [shape=box]
- RESOLVED_UNIT8 -> InferStaticVariableTypeTask
- RESOLVED_UNIT8 -> InferStaticVariableTypesInUnitTask
- RESOLVED_UNIT8 -> PropagateVariableTypesInLibraryTask
+ RESOLVED_UNIT8 -> ResolveInstanceFieldsInUnitTask
RESOLVED_UNIT8 [shape=box]
- RESOLVED_UNIT9 -> ResolveInstanceFieldsInUnitTask
+ RESOLVED_UNIT9 -> InferInstanceMembersInUnitTask
RESOLVED_UNIT9 [shape=box]
RESOLVE_TYPE_BOUNDS_ERRORS -> LibraryUnitErrorsTask
RESOLVE_TYPE_BOUNDS_ERRORS [shape=box]
@@ -297,13 +278,13 @@
RESOLVE_UNIT_ERRORS [shape=box]
ReadyLibraryElement2Task -> READY_LIBRARY_ELEMENT2
ReadyLibraryElement5Task -> READY_LIBRARY_ELEMENT6
- ReadyLibraryElement6Task -> READY_LIBRARY_ELEMENT7
+ ReadyLibraryElement7Task -> READY_LIBRARY_ELEMENT7
ReadyResolvedUnitTask -> READY_RESOLVED_UNIT
ResolveConstantExpressionTask -> CONSTANT_EXPRESSION_RESOLVED
ResolveDirectiveElementsTask -> CREATED_RESOLVED_UNIT2
ResolveDirectiveElementsTask -> RESOLVED_UNIT2
- ResolveInstanceFieldsInUnitTask -> CREATED_RESOLVED_UNIT10
- ResolveInstanceFieldsInUnitTask -> RESOLVED_UNIT10
+ ResolveInstanceFieldsInUnitTask -> CREATED_RESOLVED_UNIT9
+ ResolveInstanceFieldsInUnitTask -> RESOLVED_UNIT9
ResolveLibraryReferencesTask -> LIBRARY_ELEMENT9
ResolveLibraryTask -> LIBRARY_ELEMENT
ResolveLibraryTypeNamesTask -> LIBRARY_ELEMENT6
@@ -312,8 +293,8 @@
ResolveTopLevelUnitTypeBoundsTask -> RESOLVED_UNIT4
ResolveTopLevelUnitTypeBoundsTask -> RESOLVE_TYPE_BOUNDS_ERRORS
ResolveUnitTask -> CONSTANT_EXPRESSIONS_DEPENDENCIES
- ResolveUnitTask -> CREATED_RESOLVED_UNIT12
- ResolveUnitTask -> RESOLVED_UNIT12
+ ResolveUnitTask -> CREATED_RESOLVED_UNIT11
+ ResolveUnitTask -> RESOLVED_UNIT11
ResolveUnitTask -> RESOLVE_UNIT_ERRORS
ResolveUnitTypeNamesTask -> CREATED_RESOLVED_UNIT5
ResolveUnitTypeNamesTask -> RESOLVED_UNIT5
@@ -321,6 +302,8 @@
ResolveVariableReferencesTask -> CREATED_RESOLVED_UNIT6
ResolveVariableReferencesTask -> RESOLVED_UNIT6
ResolveVariableReferencesTask -> VARIABLE_REFERENCE_ERRORS
+ ResolvedUnit7InLibraryClosureTask -> LIBRARY_ELEMENT8
+ ResolvedUnit7InLibraryTask -> LIBRARY_ELEMENT7
SCAN_ERRORS -> dartErrorsForSource
SCAN_ERRORS [shape=box]
SOURCE_KIND -> BuildDirectiveElementsTask
@@ -347,7 +330,6 @@
TYPE_PROVIDER -> InferInstanceMembersInUnitTask
TYPE_PROVIDER -> InferStaticVariableTypeTask
TYPE_PROVIDER -> PartiallyResolveUnitReferencesTask
- TYPE_PROVIDER -> PropagateVariableTypeTask
TYPE_PROVIDER -> ResolveInstanceFieldsInUnitTask
TYPE_PROVIDER -> ResolveLibraryTypeNamesTask
TYPE_PROVIDER -> ResolveTopLevelUnitTypeBoundsTask
diff --git a/pkg/compiler/lib/src/kernel/kernel_visitor.dart b/pkg/compiler/lib/src/kernel/kernel_visitor.dart
index 68945d0..8c81f19 100644
--- a/pkg/compiler/lib/src/kernel/kernel_visitor.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_visitor.dart
@@ -205,6 +205,8 @@
return node;
}
+ final Map<ir.Node, Node> nodeToAst = <ir.Node, Node>{};
+
bool isVoidContext = false;
KernelVisitor(this.currentElement, this.elements, this.kernel);
@@ -898,7 +900,9 @@
@override
ir.SymbolLiteral visitLiteralSymbol(LiteralSymbol node) {
- return new ir.SymbolLiteral(node.slowNameString);
+ var result = new ir.SymbolLiteral(node.slowNameString);
+ nodeToAst[result] = node;
+ return result;
}
@override
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index e44ebf3..83f22ab 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -417,9 +417,6 @@
Map<JumpTarget, JumpHandler> jumpTargets = <JumpTarget, JumpHandler>{};
- // We build the Ssa graph by simulating a stack machine.
- List<HInstruction> stack = <HInstruction>[];
-
/// Returns `true` if the current element is an `async` function.
bool get isBuildingAsyncFunction {
Element element = sourceElement;
@@ -1906,23 +1903,10 @@
return graph;
}
- void push(HInstruction instruction) {
- add(instruction);
- stack.add(instruction);
- }
-
void pushWithPosition(HInstruction instruction, ast.Node node) {
push(attachPosition(instruction, node));
}
- HInstruction pop() {
- return stack.removeLast();
- }
-
- void dup() {
- stack.add(stack.last);
- }
-
HInstruction popBoolified() {
HInstruction value = pop();
if (_checkOrTrustTypes) {
@@ -4915,7 +4899,7 @@
instruction = new HInvokeStatic(element.declaration, arguments, typeMask,
targetCanThrow: targetCanThrow)
..sourceInformation = sourceInformation;
- if (!currentInlinedInstantiations.isEmpty) {
+ if (currentInlinedInstantiations.isNotEmpty) {
instruction.instantiatedTypes =
new List<DartType>.from(currentInlinedInstantiations);
}
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index a44ea37..9c91c0f 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -4,16 +4,21 @@
import 'package:kernel/ast.dart' as ir;
-import '../common/codegen.dart' show CodegenWorkItem;
+import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
import '../common/tasks.dart' show CompilerTask;
import '../compiler.dart';
+import '../diagnostics/spannable.dart';
import '../elements/elements.dart';
import '../io/source_information.dart';
import '../js_backend/backend.dart' show JavaScriptBackend;
import '../kernel/kernel.dart';
import '../kernel/kernel_visitor.dart';
import '../resolution/tree_elements.dart';
+import '../tree/dartstring.dart';
+import '../types/masks.dart';
+
import 'graph_builder.dart';
+import 'kernel_ast_adapter.dart';
import 'locals_handler.dart';
import 'nodes.dart';
@@ -44,8 +49,10 @@
element,
work.resolvedAst,
backend.compiler,
+ work.registry,
sourceInformationFactory,
- visitor.nodeToElement);
+ visitor,
+ kernel);
return builder.build();
});
}
@@ -56,20 +63,23 @@
final FunctionElement functionElement;
final ResolvedAst resolvedAst;
final Compiler compiler;
- final Map<ir.Node, Element> nodeToElement;
+ final CodegenRegistry registry;
JavaScriptBackend get backend => compiler.backend;
LocalsHandler localsHandler;
SourceInformationBuilder sourceInformationBuilder;
+ KernelAstAdapter astAdapter;
KernelSsaBuilder(
this.function,
this.functionElement,
this.resolvedAst,
this.compiler,
+ this.registry,
SourceInformationStrategy sourceInformationFactory,
- this.nodeToElement) {
+ KernelVisitor visitor,
+ Kernel kernel) {
graph.element = functionElement;
// TODO(het): Should sourceInformationBuilder be in GraphBuilder?
this.sourceInformationBuilder =
@@ -78,6 +88,8 @@
sourceInformationBuilder.buildVariableDeclaration();
this.localsHandler =
new LocalsHandler(this, functionElement, null, compiler);
+ this.astAdapter = new KernelAstAdapter(compiler.backend, resolvedAst,
+ visitor.nodeToAst, visitor.nodeToElement, kernel.functions);
}
HGraph build() {
@@ -116,4 +128,111 @@
if (!isAborted()) closeAndGotoExit(new HGoto());
graph.finalize();
}
+
+ @override
+ void visitBlock(ir.Block block) {
+ assert(!isAborted());
+ for (ir.Statement statement in block.statements) {
+ statement.accept(this);
+ if (!isReachable) {
+ // The block has been aborted by a return or a throw.
+ if (stack.isNotEmpty) {
+ compiler.reporter.internalError(
+ NO_LOCATION_SPANNABLE, 'Non-empty instruction stack.');
+ }
+ return;
+ }
+ }
+ assert(!current.isClosed());
+ if (stack.isNotEmpty) {
+ compiler.reporter
+ .internalError(NO_LOCATION_SPANNABLE, 'Non-empty instruction stack');
+ }
+ }
+
+ @override
+ void visitReturnStatement(ir.ReturnStatement returnStatement) {
+ HInstruction value;
+ if (returnStatement.expression == null) {
+ value = graph.addConstantNull(compiler);
+ } else {
+ returnStatement.expression.accept(this);
+ value = pop();
+ // TODO(het): Check or trust the type of value
+ }
+ // TODO(het): Add source information
+ // TODO(het): Set a return value instead of closing the function when we
+ // support inlining.
+ closeAndGotoExit(new HReturn(value, null));
+ }
+
+ @override
+ void visitIntLiteral(ir.IntLiteral intLiteral) {
+ stack.add(graph.addConstantInt(intLiteral.value, compiler));
+ }
+
+ @override
+ visitDoubleLiteral(ir.DoubleLiteral doubleLiteral) {
+ stack.add(graph.addConstantDouble(doubleLiteral.value, compiler));
+ }
+
+ @override
+ visitBoolLiteral(ir.BoolLiteral boolLiteral) {
+ stack.add(graph.addConstantBool(boolLiteral.value, compiler));
+ }
+
+ @override
+ visitStringLiteral(ir.StringLiteral stringLiteral) {
+ stack.add(graph.addConstantString(
+ new DartString.literal(stringLiteral.value), compiler));
+ }
+
+ @override
+ visitSymbolLiteral(ir.SymbolLiteral symbolLiteral) {
+ stack.add(graph.addConstant(
+ astAdapter.getConstantForSymbol(symbolLiteral), compiler));
+ registry?.registerConstSymbol(symbolLiteral.value);
+ }
+
+ @override
+ visitNullLiteral(ir.NullLiteral nullLiteral) {
+ stack.add(graph.addConstantNull(compiler));
+ }
+
+ @override
+ visitVariableGet(ir.VariableGet variableGet) {
+ LocalElement local = astAdapter.getElement(variableGet.variable);
+ stack.add(localsHandler.readLocal(local));
+ }
+
+ @override
+ visitStaticInvocation(ir.StaticInvocation invocation) {
+ List<HInstruction> inputs = <HInstruction>[];
+
+ for (ir.Expression argument in invocation.arguments.positional) {
+ argument.accept(this);
+ inputs.add(pop());
+ }
+ for (ir.NamedExpression argument in invocation.arguments.named) {
+ argument.value.accept(this);
+ inputs.add(pop());
+ }
+
+ ir.Procedure target = invocation.target;
+ bool targetCanThrow = astAdapter.getCanThrow(target);
+ TypeMask typeMask = astAdapter.returnTypeOf(target);
+
+ HInstruction instruction = new HInvokeStatic(
+ astAdapter.getElement(target).declaration, inputs, typeMask,
+ targetCanThrow: targetCanThrow);
+ instruction.sideEffects = astAdapter.getSideEffects(target);
+
+ push(instruction);
+ }
+
+ @override
+ visitExpressionStatement(ir.ExpressionStatement exprStatement) {
+ exprStatement.expression.accept(this);
+ pop();
+ }
}
diff --git a/pkg/compiler/lib/src/ssa/graph_builder.dart b/pkg/compiler/lib/src/ssa/graph_builder.dart
index 969899f..1c4c689 100644
--- a/pkg/compiler/lib/src/ssa/graph_builder.dart
+++ b/pkg/compiler/lib/src/ssa/graph_builder.dart
@@ -14,6 +14,25 @@
/// Holds the resulting SSA graph.
final HGraph graph = new HGraph();
+ /// A stack of instructions.
+ ///
+ /// We build the SSA graph by simulating a stack machine.
+ List<HInstruction> stack = <HInstruction>[];
+
+
+ void push(HInstruction instruction) {
+ add(instruction);
+ stack.add(instruction);
+ }
+
+ HInstruction pop() {
+ return stack.removeLast();
+ }
+
+ void dup() {
+ stack.add(stack.last);
+ }
+
HBasicBlock _current;
/// The current block to add instructions to. Might be null, if we are
diff --git a/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart b/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart
new file mode 100644
index 0000000..2076899
--- /dev/null
+++ b/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:kernel/ast.dart' as ir;
+
+import '../constants/values.dart';
+import '../diagnostics/invariant.dart';
+import '../elements/elements.dart';
+import '../js_backend/js_backend.dart';
+import '../tree/tree.dart' as ast;
+import '../types/masks.dart';
+import '../universe/side_effects.dart';
+
+import 'types.dart';
+
+/// A helper class that abstracts all accesses of the AST from Kernel nodes.
+///
+/// The goal is to remove all need for the AST from the Kernel SSA builder.
+class KernelAstAdapter {
+ final JavaScriptBackend _backend;
+ final ResolvedAst _resolvedAst;
+ final Map<ir.Node, ast.Node> _nodeToAst;
+ final Map<ir.Node, Element> _nodeToElement;
+
+ KernelAstAdapter(this._backend, this._resolvedAst, this._nodeToAst,
+ this._nodeToElement, Map<FunctionElement, ir.Member> functions) {
+ for (FunctionElement functionElement in functions.keys) {
+ _nodeToElement[functions[functionElement]] = functionElement;
+ }
+ }
+
+ ConstantValue getConstantForSymbol(ir.SymbolLiteral node) {
+ ast.Node astNode = _nodeToAst[node];
+ ConstantValue constantValue = _backend.constants
+ .getConstantValueForNode(astNode, _resolvedAst.elements);
+ assert(invariant(astNode, constantValue != null,
+ message: 'No constant computed for $node'));
+ return constantValue;
+ }
+
+ Element getElement(ir.Node node) {
+ Element result = _nodeToElement[node];
+ assert(result != null);
+ return result;
+ }
+
+ bool getCanThrow(ir.Procedure procedure) {
+ FunctionElement function = getElement(procedure);
+ return !_backend.compiler.world.getCannotThrow(function);
+ }
+
+ TypeMask returnTypeOf(ir.Procedure node) {
+ return TypeMaskFactory.inferredReturnTypeForElement(
+ getElement(node), _backend.compiler);
+ }
+
+ SideEffects getSideEffects(ir.Node node) {
+ return _backend.compiler.world.getSideEffectsOfElement(getElement(node));
+ }
+}
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index 6ed6aef..929cb77 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -1262,8 +1262,9 @@
HBasicBlock otherBlock = other.block;
for (int i = 0, length = usedBy.length; i < length; i++) {
HInstruction current = usedBy[i];
- if (otherBlock.dominates(current.block)) {
- if (identical(current.block, otherBlock)) usersInCurrentBlock++;
+ HBasicBlock currentBlock = current.block;
+ if (otherBlock.dominates(currentBlock)) {
+ if (identical(currentBlock, otherBlock)) usersInCurrentBlock++;
users.add(current);
}
}
diff --git a/pkg/compiler/lib/src/ssa/types_propagation.dart b/pkg/compiler/lib/src/ssa/types_propagation.dart
index 7564176..298d928 100644
--- a/pkg/compiler/lib/src/ssa/types_propagation.dart
+++ b/pkg/compiler/lib/src/ssa/types_propagation.dart
@@ -361,31 +361,47 @@
TypeMask receiverType = receiver.instructionType;
instruction.mask = receiverType;
- // Try to specialize the receiver after this call.
- if (receiver.dominatedUsers(instruction).length != 1 &&
- !instruction.selector.isClosureCall) {
- TypeMask newType = compiler.world.allFunctions
- .receiverType(instruction.selector, instruction.mask);
- newType = newType.intersection(receiverType, classWorld);
+ // Try to specialize the receiver after this call by instering a refinement
+ // node (HTypeKnown). There are two potentially expensive tests - are there
+ // any uses of the receiver dominated by and following this call?, and what
+ // is the refined type? The first is expensive if the receiver has many
+ // uses, the second is expensive if many classes implement the selector. So
+ // we try to do the least expensive test first.
+ const int _MAX_QUICK_USERS = 50;
+ if (!instruction.selector.isClosureCall) {
+ TypeMask newType;
+ TypeMask computeNewType() {
+ newType = compiler.world.allFunctions
+ .receiverType(instruction.selector, instruction.mask);
+ newType = newType.intersection(receiverType, classWorld);
+ return newType;
+ }
+
var next = instruction.next;
if (next is HTypeKnown && next.checkedInput == receiver) {
- // We already have refined [receiver]. We still update the
- // type of the [HTypeKnown] instruction because it may have
- // been refined with a correct type at the time, but
- // incorrect now.
- if (next.instructionType != newType) {
+ // On a previous pass or iteration we already refined [receiver] by
+ // inserting a [HTypeKnown] instruction. That replaced several dominated
+ // uses with the refinement. We update the type of the [HTypeKnown]
+ // instruction because it may have been refined with a correct type at
+ // the time, but incorrect now.
+ if (next.instructionType != computeNewType()) {
next.knownType = next.instructionType = newType;
addDependentInstructionsToWorkList(next);
}
- } else if (newType != receiverType) {
- // Insert a refinement node after the call and update all
- // users dominated by the call to use that node instead of
- // [receiver].
- HTypeKnown converted =
- new HTypeKnown.witnessed(newType, receiver, instruction);
- instruction.block.addBefore(instruction.next, converted);
- receiver.replaceAllUsersDominatedBy(converted.next, converted);
- addDependentInstructionsToWorkList(converted);
+ } else {
+ bool hasCandidates() => receiver.dominatedUsers(instruction).length > 1;
+
+ if ((receiver.usedBy.length <= _MAX_QUICK_USERS)
+ ? (hasCandidates() && computeNewType() != receiverType)
+ : (computeNewType() != receiverType && hasCandidates())) {
+ // Insert a refinement node after the call and update all users
+ // dominated by the call to use that node instead of [receiver].
+ HTypeKnown converted =
+ new HTypeKnown.witnessed(newType, receiver, instruction);
+ instruction.block.addBefore(instruction.next, converted);
+ receiver.replaceAllUsersDominatedBy(converted.next, converted);
+ addDependentInstructionsToWorkList(converted);
+ }
}
}
diff --git a/pkg/compiler/lib/src/types/flat_type_mask.dart b/pkg/compiler/lib/src/types/flat_type_mask.dart
index f38c6f6..59b573a 100644
--- a/pkg/compiler/lib/src/types/flat_type_mask.dart
+++ b/pkg/compiler/lib/src/types/flat_type_mask.dart
@@ -681,19 +681,20 @@
subclassesToCheck.any(needsNoSuchMethod);
}
- Element locateSingleElement(
- Selector selector, TypeMask mask, Compiler compiler) {
+ Element locateSingleElement(Selector selector, Compiler compiler) {
if (isEmptyOrNull) return null;
Iterable<Element> targets =
- compiler.world.allFunctions.filter(selector, mask);
+ compiler.world.allFunctions.filter(selector, this);
if (targets.length != 1) return null;
Element result = targets.first;
ClassElement enclosing = result.enclosingClass;
- // We only return the found element if it is guaranteed to be
- // implemented on the exact receiver type. It could be found in a
- // subclass or in an inheritance-wise unrelated class in case of
- // subtype selectors.
- return (base.isSubclassOf(enclosing)) ? result : null;
+ // We only return the found element if it is guaranteed to be implemented on
+ // all classes in the receiver type [this]. It could be found only in a
+ // subclass or in an inheritance-wise unrelated class in case of subtype
+ // selectors.
+ if (isSubtype) return null;
+ if (base.isSubclassOf(enclosing)) return result;
+ return null;
}
bool operator ==(var other) {
diff --git a/pkg/compiler/lib/src/types/forwarding_type_mask.dart b/pkg/compiler/lib/src/types/forwarding_type_mask.dart
index bc9ce15..d886e99 100644
--- a/pkg/compiler/lib/src/types/forwarding_type_mask.dart
+++ b/pkg/compiler/lib/src/types/forwarding_type_mask.dart
@@ -101,9 +101,8 @@
return forwardTo.canHit(element, selector, classWorld);
}
- Element locateSingleElement(
- Selector selector, TypeMask mask, Compiler compiler) {
- return forwardTo.locateSingleElement(selector, mask, compiler);
+ Element locateSingleElement(Selector selector, Compiler compiler) {
+ return forwardTo.locateSingleElement(selector, compiler);
}
bool equalsDisregardNull(other) {
diff --git a/pkg/compiler/lib/src/types/type_mask.dart b/pkg/compiler/lib/src/types/type_mask.dart
index 698d87e..d14bd95 100644
--- a/pkg/compiler/lib/src/types/type_mask.dart
+++ b/pkg/compiler/lib/src/types/type_mask.dart
@@ -358,6 +358,5 @@
* on this mask. Returns null if there is none.
*/
// TODO(johnniwinther): Move this method to [World].
- Element locateSingleElement(
- Selector selector, TypeMask mask, Compiler compiler);
+ Element locateSingleElement(Selector selector, Compiler compiler);
}
diff --git a/pkg/compiler/lib/src/types/union_type_mask.dart b/pkg/compiler/lib/src/types/union_type_mask.dart
index 0f96e10..32e4e2a 100644
--- a/pkg/compiler/lib/src/types/union_type_mask.dart
+++ b/pkg/compiler/lib/src/types/union_type_mask.dart
@@ -331,11 +331,10 @@
return disjointMasks.any((e) => e.canHit(element, selector, classWorld));
}
- Element locateSingleElement(
- Selector selector, TypeMask mask, Compiler compiler) {
+ Element locateSingleElement(Selector selector, Compiler compiler) {
Element candidate;
for (FlatTypeMask mask in disjointMasks) {
- Element current = mask.locateSingleElement(selector, mask, compiler);
+ Element current = mask.locateSingleElement(selector, compiler);
if (current == null) {
return null;
} else if (candidate == null) {
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index 19fb9a2..88cd294 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -727,7 +727,7 @@
Element locateSingleElement(Selector selector, TypeMask mask) {
mask ??= compiler.commonMasks.dynamicType;
- return mask.locateSingleElement(selector, mask, compiler);
+ return mask.locateSingleElement(selector, compiler);
}
TypeMask extendMaskIfReachesAll(Selector selector, TypeMask mask) {
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index 49825b6..4fcaa30 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -568,6 +568,7 @@
]
libs = [
"launchpad",
+ "magenta",
"runtime",
]
}
diff --git a/runtime/bin/directory_fuchsia.cc b/runtime/bin/directory_fuchsia.cc
index 1e374d1..1593ff7 100644
--- a/runtime/bin/directory_fuchsia.cc
+++ b/runtime/bin/directory_fuchsia.cc
@@ -143,38 +143,89 @@
bool Directory::SetCurrent(const char* path) {
- UNIMPLEMENTED();
- return false;
+ return (NO_RETRY_EXPECTED(chdir(path)) == 0);
}
bool Directory::Create(const char* dir_name) {
- UNIMPLEMENTED();
- return false;
+ // Create the directory with the permissions specified by the
+ // process umask.
+ int result = NO_RETRY_EXPECTED(mkdir(dir_name, 0777));
+ // If the directory already exists, treat it as a success.
+ if ((result == -1) && (errno == EEXIST)) {
+ return (Exists(dir_name) == EXISTS);
+ }
+ return (result == 0);
}
const char* Directory::SystemTemp() {
- UNIMPLEMENTED();
- return NULL;
+ PathBuffer path;
+ const char* temp_dir = getenv("TMPDIR");
+ if (temp_dir == NULL) {
+ temp_dir = getenv("TMP");
+ }
+ if (temp_dir == NULL) {
+ temp_dir = "/tmp";
+ }
+ if (!path.Add(temp_dir)) {
+ return NULL;
+ }
+
+ // Remove any trailing slash.
+ char* result = path.AsString();
+ int length = strlen(result);
+ if ((length > 1) && (result[length - 1] == '/')) {
+ result[length - 1] = '\0';
+ }
+ return path.AsScopedString();
}
const char* Directory::CreateTemp(const char* prefix) {
- UNIMPLEMENTED();
- return NULL;
+ // Returns a new, unused directory name, adding characters to the end
+ // of prefix. Creates the directory with the permissions specified
+ // by the process umask.
+ // The return value is Dart_ScopeAllocated.
+ PathBuffer path;
+ if (!path.Add(prefix)) {
+ return NULL;
+ }
+ if (!path.Add("XXXXXX")) {
+ // Pattern has overflowed.
+ return NULL;
+ }
+ char* result;
+ do {
+ result = mkdtemp(path.AsString());
+ } while ((result == NULL) && (errno == EINTR));
+ if (result == NULL) {
+ return NULL;
+ }
+ return path.AsScopedString();
}
bool Directory::Delete(const char* dir_name, bool recursive) {
- UNIMPLEMENTED();
- return false;
+ if (!recursive) {
+ if ((File::GetType(dir_name, false) == File::kIsLink) &&
+ (File::GetType(dir_name, true) == File::kIsDirectory)) {
+ return NO_RETRY_EXPECTED(unlink(dir_name)) == 0;
+ }
+ return NO_RETRY_EXPECTED(rmdir(dir_name)) == 0;
+ } else {
+ UNIMPLEMENTED();
+ return false;
+ }
}
bool Directory::Rename(const char* path, const char* new_path) {
- UNIMPLEMENTED();
- return false;
+ ExistsResult exists = Exists(path);
+ if (exists != EXISTS) {
+ return false;
+ }
+ return (NO_RETRY_EXPECTED(rename(path, new_path)) == 0);
}
} // namespace bin
diff --git a/runtime/bin/directory_test.cc b/runtime/bin/directory_test.cc
index d5b8175..35c0d22 100644
--- a/runtime/bin/directory_test.cc
+++ b/runtime/bin/directory_test.cc
@@ -28,8 +28,7 @@
const char* current = dart::bin::Directory::Current();
EXPECT_NOTNULL(current);
- dart::bin::Directory::ExistsResult r =
- dart::bin::Directory::Exists(current);
+ dart::bin::Directory::ExistsResult r = dart::bin::Directory::Exists(current);
EXPECT_EQ(dart::bin::Directory::EXISTS, r);
}
@@ -40,6 +39,16 @@
}
+TEST_CASE(DirectorySystemTempExists) {
+ const char* system_temp = dart::bin::Directory::SystemTemp();
+ EXPECT_NOTNULL(system_temp);
+
+ dart::bin::Directory::ExistsResult r =
+ dart::bin::Directory::Exists(system_temp);
+ EXPECT_EQ(dart::bin::Directory::EXISTS, r);
+}
+
+
TEST_CASE(DirectoryCreateTemp) {
const char* kTempPrefix = "test_prefix";
const char* system_temp = dart::bin::Directory::SystemTemp();
@@ -75,7 +84,7 @@
TEST_CASE(DirectoryCreateDelete) {
- const char* kTempDirName = "test_name";
+ const char* kTempDirName = "create_delete_test_name";
const char* system_temp = dart::bin::Directory::SystemTemp();
EXPECT_NOTNULL(system_temp);
@@ -100,7 +109,7 @@
TEST_CASE(DirectoryRename) {
- const char* kTempDirName = "test_name";
+ const char* kTempDirName = "rename_test_name";
const char* system_temp = dart::bin::Directory::SystemTemp();
EXPECT_NOTNULL(system_temp);
diff --git a/runtime/bin/loader.cc b/runtime/bin/loader.cc
index 2220478..122e851 100644
--- a/runtime/bin/loader.cc
+++ b/runtime/bin/loader.cc
@@ -667,6 +667,7 @@
}
// All cases should have been handled above.
UNREACHABLE();
+ return Dart_Null();
}
diff --git a/runtime/bin/run_vm_tests_fuchsia.cc b/runtime/bin/run_vm_tests_fuchsia.cc
index b75881d..35eee46 100644
--- a/runtime/bin/run_vm_tests_fuchsia.cc
+++ b/runtime/bin/run_vm_tests_fuchsia.cc
@@ -104,6 +104,11 @@
const char* kBugs[] = {
// Needs NativeSymbolResolver
"Service_PersistentHandles",
+ // Needs lstat
+ "DirectoryCreateTemp",
+ "DirectoryCreateDelete",
+ // Needs rename
+ "DirectoryRename",
};
diff --git a/runtime/bin/vmservice/server.dart b/runtime/bin/vmservice/server.dart
index 43186d1..c237c9e 100644
--- a/runtime/bin/vmservice/server.dart
+++ b/runtime/bin/vmservice/server.dart
@@ -59,8 +59,10 @@
Uint8List cstring = result[0];
socket.addUtf8Text(cstring);
}
- } catch (_) {
+ } catch (e, st) {
print("Ignoring error posting over WebSocket.");
+ print(e);
+ print(st);
}
}
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 42ba0f2..9ea762d 100755
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -586,13 +586,6 @@
Dart_GcPrologueCallback prologue_callback,
Dart_GcEpilogueCallback epilogue_callback);
-typedef void (*Dart_GcPrologueWeakHandleCallback)(void* isolate_callback_data,
- Dart_WeakPersistentHandle obj,
- intptr_t num_native_fields,
- intptr_t* native_fields);
-
-DART_EXPORT Dart_Handle Dart_VisitPrologueWeakHandles(
- Dart_GcPrologueWeakHandleCallback callback);
/*
* ==========================
diff --git a/runtime/lib/internal_patch.dart b/runtime/lib/internal_patch.dart
index 24f31de..d19430f 100644
--- a/runtime/lib/internal_patch.dart
+++ b/runtime/lib/internal_patch.dart
@@ -32,10 +32,6 @@
static var platformScript;
}
-@patch class CodeUnits {
- static final int cid = ClassID.getID(new CodeUnits(""));
-}
-
final bool is64Bit = _inquireIs64Bit();
bool _inquireIs64Bit() native "Internal_inquireIs64Bit";
diff --git a/runtime/lib/typed_data.dart b/runtime/lib/typed_data.dart
index d8b4324..c010555 100644
--- a/runtime/lib/typed_data.dart
+++ b/runtime/lib/typed_data.dart
@@ -1273,7 +1273,7 @@
}
void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) {
- if (ClassID.getID(iterable) == CodeUnits.cid) {
+ if (iterable is CodeUnits) {
end = RangeError.checkValidRange(start, end, this.length);
int length = end - start;
int byteStart = this.offsetInBytes + start * Int16List.BYTES_PER_ELEMENT;
@@ -1339,7 +1339,7 @@
}
void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) {
- if (ClassID.getID(iterable) == CodeUnits.cid) {
+ if (iterable is CodeUnits) {
end = RangeError.checkValidRange(start, end, this.length);
int length = end - start;
int byteStart = this.offsetInBytes + start * Uint16List.BYTES_PER_ELEMENT;
@@ -3384,7 +3384,7 @@
}
void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) {
- if (ClassID.getID(iterable) == CodeUnits.cid) {
+ if (iterable is CodeUnits) {
end = RangeError.checkValidRange(start, end, this.length);
int length = end - start;
int byteStart = this.offsetInBytes + start * Int16List.BYTES_PER_ELEMENT;
@@ -3442,7 +3442,7 @@
}
void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) {
- if (ClassID.getID(iterable) == CodeUnits.cid) {
+ if (iterable is CodeUnits) {
end = RangeError.checkValidRange(start, end, this.length);
int length = end - start;
int byteStart = this.offsetInBytes + start * Uint16List.BYTES_PER_ELEMENT;
diff --git a/runtime/observatory/lib/elements.dart b/runtime/observatory/lib/elements.dart
index efd2cb0..b915df1 100644
--- a/runtime/observatory/lib/elements.dart
+++ b/runtime/observatory/lib/elements.dart
@@ -6,12 +6,7 @@
export 'package:observatory/src/elements/class_view.dart';
export 'package:observatory/src/elements/code_view.dart';
export 'package:observatory/src/elements/debugger.dart';
-export 'package:observatory/src/elements/error_view.dart';
-export 'package:observatory/src/elements/eval_box.dart';
export 'package:observatory/src/elements/eval_link.dart';
-export 'package:observatory/src/elements/field_view.dart';
-export 'package:observatory/src/elements/function_view.dart';
-export 'package:observatory/src/elements/heap_map.dart';
export 'package:observatory/src/elements/instance_view.dart';
export 'package:observatory/src/elements/isolate_reconnect.dart';
export 'package:observatory/src/elements/isolate_summary.dart';
@@ -20,15 +15,9 @@
export 'package:observatory/src/elements/library_ref_as_value.dart';
export 'package:observatory/src/elements/library_view.dart';
export 'package:observatory/src/elements/logging.dart';
-export 'package:observatory/src/elements/megamorphiccache_view.dart';
export 'package:observatory/src/elements/metrics.dart';
export 'package:observatory/src/elements/object_view.dart';
-export 'package:observatory/src/elements/objectpool_view.dart';
-export 'package:observatory/src/elements/objectstore_view.dart';
export 'package:observatory/src/elements/observatory_element.dart';
-export 'package:observatory/src/elements/persistent_handles.dart';
-export 'package:observatory/src/elements/script_inset.dart';
-export 'package:observatory/src/elements/script_view.dart';
export 'package:observatory/src/elements/service_ref.dart';
export 'package:observatory/src/elements/service_view.dart';
export 'package:observatory/src/elements/timeline_page.dart';
@@ -55,12 +44,18 @@
import 'package:observatory/src/elements/curly_block_wrapper.dart';
import 'package:observatory/src/elements/error_ref.dart';
import 'package:observatory/src/elements/error_ref_wrapper.dart';
+import 'package:observatory/src/elements/error_view.dart';
+import 'package:observatory/src/elements/eval_box.dart';
+import 'package:observatory/src/elements/eval_box_wrapper.dart';
import 'package:observatory/src/elements/field_ref.dart';
import 'package:observatory/src/elements/field_ref_wrapper.dart';
+import 'package:observatory/src/elements/field_view.dart';
import 'package:observatory/src/elements/flag_list.dart';
import 'package:observatory/src/elements/function_ref.dart';
import 'package:observatory/src/elements/function_ref_wrapper.dart';
+import 'package:observatory/src/elements/function_view.dart';
import 'package:observatory/src/elements/general_error.dart';
+import 'package:observatory/src/elements/heap_map.dart';
import 'package:observatory/src/elements/heap_snapshot.dart';
import 'package:observatory/src/elements/icdata_ref.dart';
import 'package:observatory/src/elements/icdata_view.dart';
@@ -76,6 +71,7 @@
import 'package:observatory/src/elements/library_ref_wrapper.dart';
import 'package:observatory/src/elements/local_var_descriptors_ref.dart';
import 'package:observatory/src/elements/megamorphiccache_ref.dart';
+import 'package:observatory/src/elements/megamorphiccache_view.dart';
import 'package:observatory/src/elements/nav/bar.dart';
import 'package:observatory/src/elements/nav/class_menu.dart';
import 'package:observatory/src/elements/nav/class_menu_wrapper.dart';
@@ -98,15 +94,23 @@
import 'package:observatory/src/elements/nav/vm_menu.dart';
import 'package:observatory/src/elements/nav/vm_menu_wrapper.dart';
import 'package:observatory/src/elements/objectpool_ref.dart';
+import 'package:observatory/src/elements/objectpool_view.dart';
import 'package:observatory/src/elements/object_common.dart';
import 'package:observatory/src/elements/object_common_wrapper.dart';
+import 'package:observatory/src/elements/objectstore_view.dart';
import 'package:observatory/src/elements/observatory_application.dart';
+import 'package:observatory/src/elements/persistent_handles.dart';
import 'package:observatory/src/elements/pc_descriptors_ref.dart';
import 'package:observatory/src/elements/ports.dart';
import 'package:observatory/src/elements/sample_buffer_control.dart';
+import 'package:observatory/src/elements/script_inset.dart';
+import 'package:observatory/src/elements/script_inset_wrapper.dart';
import 'package:observatory/src/elements/script_ref.dart';
import 'package:observatory/src/elements/script_ref_wrapper.dart';
+import 'package:observatory/src/elements/script_view.dart';
import 'package:observatory/src/elements/sentinel_value.dart';
+import 'package:observatory/src/elements/source_inset.dart';
+import 'package:observatory/src/elements/source_inset_wrapper.dart';
import 'package:observatory/src/elements/source_link.dart';
import 'package:observatory/src/elements/source_link_wrapper.dart';
import 'package:observatory/src/elements/stack_trace_tree_config.dart';
@@ -131,10 +135,15 @@
export 'package:observatory/src/elements/cpu_profile_table.dart';
export 'package:observatory/src/elements/curly_block.dart';
export 'package:observatory/src/elements/error_ref.dart';
+export 'package:observatory/src/elements/error_view.dart';
+export 'package:observatory/src/elements/eval_box.dart';
export 'package:observatory/src/elements/field_ref.dart';
+export 'package:observatory/src/elements/field_view.dart';
+export 'package:observatory/src/elements/function_view.dart';
export 'package:observatory/src/elements/flag_list.dart';
export 'package:observatory/src/elements/function_ref.dart';
export 'package:observatory/src/elements/general_error.dart';
+export 'package:observatory/src/elements/heap_map.dart';
export 'package:observatory/src/elements/heap_snapshot.dart';
export 'package:observatory/src/elements/icdata_ref.dart';
export 'package:observatory/src/elements/icdata_view.dart';
@@ -146,6 +155,7 @@
export 'package:observatory/src/elements/library_ref.dart';
export 'package:observatory/src/elements/local_var_descriptors_ref.dart';
export 'package:observatory/src/elements/megamorphiccache_ref.dart';
+export 'package:observatory/src/elements/megamorphiccache_view.dart';
export 'package:observatory/src/elements/nav/bar.dart';
export 'package:observatory/src/elements/nav/class_menu.dart';
export 'package:observatory/src/elements/nav/isolate_menu.dart';
@@ -159,13 +169,19 @@
export 'package:observatory/src/elements/nav/top_menu.dart';
export 'package:observatory/src/elements/nav/vm_menu.dart';
export 'package:observatory/src/elements/objectpool_ref.dart';
+export 'package:observatory/src/elements/objectpool_view.dart';
+export 'package:observatory/src/elements/objectstore_view.dart';
export 'package:observatory/src/elements/object_common.dart';
export 'package:observatory/src/elements/observatory_application.dart';
+export 'package:observatory/src/elements/persistent_handles.dart';
export 'package:observatory/src/elements/pc_descriptors_ref.dart';
export 'package:observatory/src/elements/ports.dart';
export 'package:observatory/src/elements/sample_buffer_control.dart';
+export 'package:observatory/src/elements/script_inset.dart';
export 'package:observatory/src/elements/script_ref.dart';
+export 'package:observatory/src/elements/script_view.dart';
export 'package:observatory/src/elements/sentinel_value.dart';
+export 'package:observatory/src/elements/source_inset.dart';
export 'package:observatory/src/elements/source_link.dart';
export 'package:observatory/src/elements/stack_trace_tree_config.dart';
export 'package:observatory/src/elements/token_stream_ref.dart';
@@ -193,12 +209,18 @@
CurlyBlockElementWrapper.tag.ensureRegistration();
ErrorRefElement.tag.ensureRegistration();
ErrorRefElementWrapper.tag.ensureRegistration();
+ ErrorViewElement.tag.ensureRegistration();
+ EvalBoxElement.tag.ensureRegistration();
+ EvalBoxElementWrapper.tag.ensureRegistration();
FieldRefElement.tag.ensureRegistration();
FieldRefElementWrapper.tag.ensureRegistration();
+ FieldViewElement.tag.ensureRegistration();
FlagListElement.tag.ensureRegistration();
FunctionRefElement.tag.ensureRegistration();
FunctionRefElementWrapper.tag.ensureRegistration();
+ FunctionViewElement.tag.ensureRegistration();
GeneralErrorElement.tag.ensureRegistration();
+ HeapMapElement.tag.ensureRegistration();
HeapSnapshotElement.tag.ensureRegistration();
ICDataRefElement.tag.ensureRegistration();
ICDataViewElement.tag.ensureRegistration();
@@ -214,6 +236,7 @@
LibraryRefElementWrapper.tag.ensureRegistration();
LocalVarDescriptorsRefElement.tag.ensureRegistration();
MegamorphicCacheRefElement.tag.ensureRegistration();
+ MegamorphicCacheViewElement.tag.ensureRegistration();
NavBarElement.tag.ensureRegistration();
NavClassMenuElement.tag.ensureRegistration();
NavClassMenuElementWrapper.tag.ensureRegistration();
@@ -238,14 +261,21 @@
ObjectCommonElement.tag.ensureRegistration();
ObjectCommonElementWrapper.tag.ensureRegistration();
ObjectPoolRefElement.tag.ensureRegistration();
+ ObjectPoolViewElement.tag.ensureRegistration();
+ ObjectStoreViewElement.tag.ensureRegistration();
ObservatoryApplicationElement.tag.ensureRegistration();
+ PersistentHandlesPageElement.tag.ensureRegistration();
PcDescriptorsRefElement.tag.ensureRegistration();
PortsElement.tag.ensureRegistration();
- ScriptRefElement.tag.ensureRegistration();
+ ScriptInsetElement.tag.ensureRegistration();
+ ScriptInsetElementWrapper.tag.ensureRegistration();
SampleBufferControlElement.tag.ensureRegistration();
ScriptRefElement.tag.ensureRegistration();
ScriptRefElementWrapper.tag.ensureRegistration();
+ ScriptViewElement.tag.ensureRegistration();
SentinelValueElement.tag.ensureRegistration();
+ SourceInsetElement.tag.ensureRegistration();
+ SourceInsetElementWrapper.tag.ensureRegistration();
SourceLinkElement.tag.ensureRegistration();
SourceLinkElementWrapper.tag.ensureRegistration();
StackTraceTreeConfigElement.tag.ensureRegistration();
diff --git a/runtime/observatory/lib/elements.html b/runtime/observatory/lib/elements.html
index 2fcf818..dd4378b 100644
--- a/runtime/observatory/lib/elements.html
+++ b/runtime/observatory/lib/elements.html
@@ -3,12 +3,7 @@
<link rel="import" href="src/elements/class_view.html">
<link rel="import" href="src/elements/code_view.html">
<link rel="import" href="src/elements/debugger.html">
-<link rel="import" href="src/elements/error_view.html">
-<link rel="import" href="src/elements/eval_box.html">
<link rel="import" href="src/elements/eval_link.html">
-<link rel="import" href="src/elements/field_view.html">
-<link rel="import" href="src/elements/function_view.html">
-<link rel="import" href="src/elements/heap_map.html">
<link rel="import" href="src/elements/instance_view.html">
<link rel="import" href="src/elements/isolate_summary.html">
<link rel="import" href="src/elements/isolate_view.html">
@@ -16,14 +11,8 @@
<link rel="import" href="src/elements/library_ref_as_value.html">
<link rel="import" href="src/elements/library_view.html">
<link rel="import" href="src/elements/logging.html">
-<link rel="import" href="src/elements/megamorphiccache_view.html">
<link rel="import" href="src/elements/metrics.html">
<link rel="import" href="src/elements/object_view.html">
-<link rel="import" href="src/elements/objectpool_view.html">
-<link rel="import" href="src/elements/objectstore_view.html">
-<link rel="import" href="src/elements/persistent_handles.html">
-<link rel="import" href="src/elements/script_inset.html">
-<link rel="import" href="src/elements/script_view.html">
<link rel="import" href="src/elements/service_ref.html">
<link rel="import" href="src/elements/service_view.html">
<link rel="import" href="src/elements/timeline_page.html">
diff --git a/runtime/observatory/lib/models.dart b/runtime/observatory/lib/models.dart
index 01178ad..bb3ee7e 100644
--- a/runtime/observatory/lib/models.dart
+++ b/runtime/observatory/lib/models.dart
@@ -35,7 +35,9 @@
part 'src/models/objects/notification.dart';
part 'src/models/objects/object.dart';
part 'src/models/objects/objectpool.dart';
+part 'src/models/objects/objectstore.dart';
part 'src/models/objects/pc_descriptors.dart';
+part 'src/models/objects/persistent_handles.dart';
part 'src/models/objects/ports.dart';
part 'src/models/objects/retaining_path.dart';
part 'src/models/objects/sample_profile.dart';
@@ -51,13 +53,20 @@
part 'src/models/repositories/allocation_profile.dart';
part 'src/models/repositories/class.dart';
part 'src/models/repositories/context.dart';
+part 'src/models/repositories/eval.dart';
part 'src/models/repositories/event.dart';
+part 'src/models/repositories/field.dart';
part 'src/models/repositories/flag.dart';
+part 'src/models/repositories/function.dart';
part 'src/models/repositories/heap_snapshot.dart';
part 'src/models/repositories/icdata.dart';
part 'src/models/repositories/inbound_references.dart';
part 'src/models/repositories/instance.dart';
+part 'src/models/repositories/megamorphiccache.dart';
part 'src/models/repositories/notification.dart';
+part 'src/models/repositories/objectpool.dart';
+part 'src/models/repositories/objectstore.dart';
+part 'src/models/repositories/persistent_handles.dart';
part 'src/models/repositories/ports.dart';
part 'src/models/repositories/reachable_size.dart';
part 'src/models/repositories/retained_size.dart';
diff --git a/runtime/observatory/lib/repositories.dart b/runtime/observatory/lib/repositories.dart
index cf6d202..006e0f2 100644
--- a/runtime/observatory/lib/repositories.dart
+++ b/runtime/observatory/lib/repositories.dart
@@ -18,13 +18,20 @@
part 'src/repositories/allocation_profile.dart';
part 'src/repositories/class.dart';
part 'src/repositories/context.dart';
+part 'src/repositories/eval.dart';
part 'src/repositories/event.dart';
+part 'src/repositories/field.dart';
part 'src/repositories/flag.dart';
+part 'src/repositories/function.dart';
part 'src/repositories/heap_snapshot.dart';
part 'src/repositories/icdata.dart';
part 'src/repositories/inbound_references.dart';
part 'src/repositories/instance.dart';
+part 'src/repositories/megamorphiccache.dart';
part 'src/repositories/notification.dart';
+part 'src/repositories/objectpool.dart';
+part 'src/repositories/objectstore.dart';
+part 'src/repositories/persistent_handles.dart';
part 'src/repositories/ports.dart';
part 'src/repositories/reachable_size.dart';
part 'src/repositories/retaining_path.dart';
diff --git a/runtime/observatory/lib/src/app/page.dart b/runtime/observatory/lib/src/app/page.dart
index bad6c88..cd2b0cd 100644
--- a/runtime/observatory/lib/src/app/page.dart
+++ b/runtime/observatory/lib/src/app/page.dart
@@ -6,7 +6,10 @@
AllocationProfileRepository _allocationProfileRepository
= new AllocationProfileRepository();
+ClassRepository _classRepository = new ClassRepository();
ContextRepository _contextRepository = new ContextRepository();
+FieldRepository _fieldRepository = new FieldRepository();
+FunctionRepository _functionRepository = new FunctionRepository();
HeapSnapshotRepository _heapSnapshotRepository
= new HeapSnapshotRepository();
ICDataRepository _icdataRepository = new ICDataRepository();
@@ -15,7 +18,16 @@
InstanceRepository _instanceRepository = new InstanceRepository();
IsolateSampleProfileRepository _isolateSampleProfileRepository
= new IsolateSampleProfileRepository();
+MegamorphicCacheRepository _megamorphicCacheRepository
+ = new MegamorphicCacheRepository();
+ObjectPoolRepository _objectPoolRepository
+ = new ObjectPoolRepository();
+ObjectStoreRepository _objectstoreRepository
+ = new ObjectStoreRepository();
+PersistentHandlesRepository _persistentHandlesRepository
+ = new PersistentHandlesRepository();
PortsRepository _portsRepository = new PortsRepository();
+ScriptRepository _scriptRepository = new ScriptRepository();
class IsolateNotFound implements Exception {
String isolateId;
@@ -181,7 +193,9 @@
assert(element != null);
}
- void _visitObject(obj) {
+ Future _visitObject(obj) async {
+ container.children = [];
+ await obj.reload();
if (obj is Context) {
container.children = [
new ContextViewElement(app.vm, obj.isolate, obj, app.events,
@@ -194,6 +208,38 @@
_instanceRepository,
queue: app.queue)
];
+ } else if (obj is DartError) {
+ container.children = [
+ new ErrorViewElement(app.notifications, obj, queue: app.queue)
+ ];
+ } else if (obj is Field) {
+ container.children = [
+ new FieldViewElement(app.vm, obj.isolate, obj, app.events,
+ app.notifications,
+ _fieldRepository,
+ _classRepository,
+ _retainedSizeRepository,
+ _reachableSizeRepository,
+ _inboundReferencesRepository,
+ _retainingPathRepository,
+ _scriptRepository,
+ _instanceRepository,
+ queue: app.queue)
+ ];
+ } else if (obj is ServiceFunction) {
+ container.children = [
+ new FunctionViewElement(app.vm, obj.isolate, obj, app.events,
+ app.notifications,
+ _functionRepository,
+ _classRepository,
+ _retainedSizeRepository,
+ _reachableSizeRepository,
+ _inboundReferencesRepository,
+ _retainingPathRepository,
+ _scriptRepository,
+ _instanceRepository,
+ queue: app.queue)
+ ];
} else if (obj is ICData) {
container.children = [
new ICDataViewElement(app.vm, obj.isolate, obj, app.events,
@@ -206,6 +252,48 @@
_instanceRepository,
queue: app.queue)
];
+ } else if (obj is MegamorphicCache) {
+ container.children = [
+ new MegamorphicCacheViewElement(app.vm, obj.isolate, obj, app.events,
+ app.notifications,
+ _megamorphicCacheRepository,
+ _retainedSizeRepository,
+ _reachableSizeRepository,
+ _inboundReferencesRepository,
+ _retainingPathRepository,
+ _instanceRepository,
+ queue: app.queue)
+ ];
+ } else if (obj is ObjectPool) {
+ container.children = [
+ new ObjectPoolViewElement(app.vm, obj.isolate, obj, app.events,
+ app.notifications,
+ _objectPoolRepository,
+ _retainedSizeRepository,
+ _reachableSizeRepository,
+ _inboundReferencesRepository,
+ _retainingPathRepository,
+ _instanceRepository,
+ queue: app.queue)
+ ];
+ } else if (obj is Script) {
+ var pos;
+ if (app.locationManager.internalArguments['pos'] != null) {
+ try {
+ pos = int.parse(app.locationManager.internalArguments['pos']);
+ } catch (_) {}
+ }
+ container.children = [
+ new ScriptViewElement(app.vm, obj.isolate, obj, app.events,
+ app.notifications,
+ _scriptRepository,
+ _retainedSizeRepository,
+ _reachableSizeRepository,
+ _inboundReferencesRepository,
+ _retainingPathRepository,
+ _instanceRepository,
+ pos: pos, queue: app.queue)
+ ];
} else {
ServiceObjectViewElement serviceElement =new Element.tag('service-view');
serviceElement.object = obj;
@@ -234,7 +322,7 @@
isolate,
app.events,
app.notifications,
- new ClassRepository(isolate))
+ _classRepository)
];
});
}
@@ -255,22 +343,30 @@
}
}
+class ObjectStorePage extends MatchingPage {
+ ObjectStorePage(app) : super('object-store', app);
-class ObjectStorePage extends SimplePage {
- ObjectStorePage(app) : super('object-store', 'objectstore-view', app);
+ final DivElement container = new DivElement();
void _visit(Uri uri) {
super._visit(uri);
- getIsolate(uri).then((isolate) {
- isolate.getObjectStore().then((objectStore) {
- if (element != null) {
- /// Update the page.
- ObjectStoreViewElement page = element;
- page.objectStore = objectStore;
- }
- });
+ getIsolate(uri).then((isolate) async {
+ container.children = [
+ new ObjectStoreViewElement(isolate.vm, isolate,
+ app.events,
+ app.notifications,
+ _objectstoreRepository,
+ _instanceRepository)
+ ];
});
}
+
+ void onInstall() {
+ if (element == null) {
+ element = container;
+ }
+ assert(element != null);
+ }
}
class CpuProfilerPage extends MatchingPage {
@@ -374,34 +470,50 @@
}
}
-class PersistentHandlesPage extends SimplePage {
- PersistentHandlesPage(app)
- : super('persistent-handles', 'persistent-handles-page', app);
+class PersistentHandlesPage extends MatchingPage {
+ PersistentHandlesPage(app) : super('persistent-handles', app);
+
+ final DivElement container = new DivElement();
void _visit(Uri uri) {
super._visit(uri);
getIsolate(uri).then((isolate) {
- if (element != null) {
- PersistentHandlesPageElement page = element;
- page.isolate = isolate;
- }
+ container.children = [
+ new PersistentHandlesPageElement(isolate.vm, isolate, app.events,
+ app.notifications,
+ _persistentHandlesRepository,
+ _instanceRepository, queue: app.queue)
+ ];
});
}
+
+ void onInstall() {
+ if (element == null) {
+ element = container;
+ }
+ }
}
-class HeapMapPage extends SimplePage {
- HeapMapPage(app) : super('heap-map', 'heap-map', app);
+class HeapMapPage extends MatchingPage {
+ HeapMapPage(app) : super('heap-map', app);
+
+ final DivElement container = new DivElement();
void _visit(Uri uri) {
super._visit(uri);
getIsolate(uri).then((isolate) {
- if (element != null) {
- /// Update the page.
- HeapMapElement page = element;
- page.isolate = isolate;
- }
+ container.children = [
+ new HeapMapElement(isolate.vm, isolate, app.events, app.notifications,
+ queue: app.queue)
+ ];
});
}
+
+ void onInstall() {
+ if (element == null) {
+ element = container;
+ }
+ }
}
class HeapSnapshotPage extends MatchingPage {
diff --git a/runtime/observatory/lib/src/elements/allocation_profile.dart b/runtime/observatory/lib/src/elements/allocation_profile.dart
index 45e4d9f..d56b2a0 100644
--- a/runtime/observatory/lib/src/elements/allocation_profile.dart
+++ b/runtime/observatory/lib/src/elements/allocation_profile.dart
@@ -128,7 +128,7 @@
new NavVMMenuElement(_vm, _events, queue: _r.queue),
new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
new NavMenuElement('allocation profile', last: true,
- link: Uris.profiler(_isolate), queue: _r.queue),
+ link: Uris.allocationProfiler(_isolate), queue: _r.queue),
new NavRefreshElement(label: 'Download', disabled: _profile == null,
queue: _r.queue)
..onRefresh.listen((_) => _downloadCSV()),
diff --git a/runtime/observatory/lib/src/elements/class_tree.dart b/runtime/observatory/lib/src/elements/class_tree.dart
index 6fefdfd..0e2aed0 100644
--- a/runtime/observatory/lib/src/elements/class_tree.dart
+++ b/runtime/observatory/lib/src/elements/class_tree.dart
@@ -115,7 +115,7 @@
_object = null;
_subclasses.clear();
_mixins.clear();
- _object = await _register(await _classes.getObject());
+ _object = await _register(await _classes.getObject(_isolate));
_r.dirty();
}
@@ -129,7 +129,7 @@
}
Future<Iterable<M.Class>> _getActualChildrens(M.ClassRef ref) async {
- var cls = await _classes.get(ref.id);
+ var cls = await _classes.get(_isolate, ref.id);
if (cls.isPatch) {
return const [];
}
diff --git a/runtime/observatory/lib/src/elements/class_view.html b/runtime/observatory/lib/src/elements/class_view.html
index 14af953..f67e7f1 100644
--- a/runtime/observatory/lib/src/elements/class_view.html
+++ b/runtime/observatory/lib/src/elements/class_view.html
@@ -1,8 +1,6 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="action_link.html">
-<link rel="import" href="eval_box.html">
<link rel="import" href="eval_link.html">
-<link rel="import" href="script_inset.html">
<polymer-element name="class-view">
<template>
@@ -114,7 +112,7 @@
<hr>
<div class="content">
- <eval-box callback="{{ evaluate }}"></eval-box>
+ <eval-box context="{{ cls }}"></eval-box>
</div>
<hr>
diff --git a/runtime/observatory/lib/src/elements/context_view.dart b/runtime/observatory/lib/src/elements/context_view.dart
index 98dcc20..4be588d 100644
--- a/runtime/observatory/lib/src/elements/context_view.dart
+++ b/runtime/observatory/lib/src/elements/context_view.dart
@@ -21,7 +21,7 @@
import 'package:observatory/src/elements/object_common.dart';
import 'package:observatory/src/elements/view_footer.dart';
-class ContextViewElement extends HtmlElement implements Renderable {
+class ContextViewElement extends HtmlElement implements Renderable {
static const tag = const Tag<ContextViewElement>('context-view',
dependencies: const [
ContextRefElement.tag,
diff --git a/runtime/observatory/lib/src/elements/cpu_profile.dart b/runtime/observatory/lib/src/elements/cpu_profile.dart
index 75e2c07..672f6d3 100644
--- a/runtime/observatory/lib/src/elements/cpu_profile.dart
+++ b/runtime/observatory/lib/src/elements/cpu_profile.dart
@@ -101,7 +101,7 @@
new NavTopMenuElement(queue: _r.queue),
new NavVMMenuElement(_vm, _events, queue: _r.queue),
new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
- new NavMenuElement('cpu profile', link: Uris.profiler(_isolate),
+ new NavMenuElement('cpu profile', link: Uris.cpuProfiler(_isolate),
last: true, queue: _r.queue),
new NavRefreshElement(queue: _r.queue)
..onRefresh.listen(_refresh),
diff --git a/runtime/observatory/lib/src/elements/cpu_profile_table.dart b/runtime/observatory/lib/src/elements/cpu_profile_table.dart
index 104b190..d7b09d7 100644
--- a/runtime/observatory/lib/src/elements/cpu_profile_table.dart
+++ b/runtime/observatory/lib/src/elements/cpu_profile_table.dart
@@ -133,7 +133,7 @@
new NavVMMenuElement(_vm, _events, queue: _r.queue),
new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
new NavMenuElement('cpu profile (table)',
- link: Uris.profiler(_isolate), last: true, queue: _r.queue),
+ link: Uris.cpuProfilerTable(_isolate), last: true, queue: _r.queue),
new NavRefreshElement(queue: _r.queue)
..onRefresh.listen(_refresh),
new NavRefreshElement(label: 'Clear', queue: _r.queue)
@@ -223,7 +223,10 @@
..text = '0%',
new SpanElement()..classes = const ['name']
];
- element.onClick.listen((_) {
+ element.onClick.listen((e) {
+ if (e.target is AnchorElement) {
+ return;
+ }
_selected = _functions.getItemFromElement(element);
_r.dirty();
});
@@ -287,7 +290,10 @@
..text = '0%',
new SpanElement()..classes = const ['name']
];
- element.onClick.listen((_) {
+ element.onClick.listen((e) {
+ if (e.target is AnchorElement) {
+ return;
+ }
_selected = _callees.getItemFromElement(element);
_r.dirty();
});
@@ -322,7 +328,10 @@
..text = '0%',
new SpanElement()..classes = const ['name']
];
- element.onClick.listen((_) {
+ element.onClick.listen((e) {
+ if (e.target is AnchorElement) {
+ return;
+ }
_selected = _callers.getItemFromElement(element);
_r.dirty();
});
diff --git a/runtime/observatory/lib/src/elements/css/shared.css b/runtime/observatory/lib/src/elements/css/shared.css
index d378e68..a914e87 100644
--- a/runtime/observatory/lib/src/elements/css/shared.css
+++ b/runtime/observatory/lib/src/elements/css/shared.css
@@ -2,13 +2,17 @@
* {
margin: 0;
padding: 0;
- font: 400 14px 'Montserrat', sans-serif;
- color: #333;
box-sizing: border-box;
}
body {
padding-top: 56px;
+ color: #333;
+ font: 400 14px 'Montserrat', sans-serif;
+}
+
+button {
+ font: 400 14px 'Montserrat', sans-serif;
}
.content {
@@ -32,6 +36,10 @@
font: 400 18px 'Montserrat', sans-serif;
}
+h2 {
+ font: 400 16px 'Montserrat', sans-serif;
+}
+
.memberList {
display: table;
}
@@ -570,6 +578,21 @@
margin-left: 0.5em;
}
+/* context-ref */
+/* TODO(cbernaschina) fix context-ref-wrapped to context-ref when wrapper
+removed */
+
+context-ref-wrapped > a[href]:hover {
+ text-decoration: underline;
+}
+context-ref-wrapped > a[href] {
+ color: #0489c3;
+ text-decoration: none;
+}
+context-ref-wrapped > a[href] * {
+ color: inherit;
+}
+
/* cpu-profile */
cpu-profile {
@@ -761,13 +784,103 @@
error-ref-wrapped > pre {
background-color: #f5f5f5;
border: 1px solid #ccc;
- padding: 10px;
+ padding-left: 10px;
+ padding-right: 10px;
font-family: consolas, courier, monospace;
font-size: 1em;
line-height: 1.2em;
white-space: pre;
}
+/* eval-box */
+/* TODO(cbernaschina) fix eval-box-wrapped to error-ref when wrapper
+removed */
+
+eval-box-wrapped a[href]:hover {
+ text-decoration: underline;
+}
+eval-box-wrapped a[href] {
+ color: #0489c3;
+ text-decoration: none;
+}
+eval-box-wrapped .quicks > button:hover {
+ background-color: transparent;
+ border: none;
+ text-decoration: underline;
+}
+eval-box-wrapped .quicks > button {
+ background-color: transparent;
+ border: none;
+ color: #0489c3;
+ padding: 0;
+ margin-right: 1em;
+ text-decoration: none;
+}
+eval-box-wrapped .empathize {
+ font-style: italic;
+}
+eval-box-wrapped .indent {
+ margin-left: 1.5em;
+ font: 400 14px 'Montserrat', sans-serif;
+ line-height: 150%;
+}
+eval-box-wrapped .stackTraceBox {
+ margin-left: 1.5em;
+ background-color: #f5f5f5;
+ border: 1px solid #ccc;
+ padding: 10px;
+ font-family: consolas, courier, monospace;
+ font-size: 12px;
+ white-space: pre;
+ overflow-x: auto;
+}
+eval-box-wrapped .heading {
+ line-height: 30px;
+ position: relative;
+ box-sizing: border-box;
+ width: 100%;
+ min-width: 450px;
+ padding-right: 150px;
+}
+eval-box-wrapped .heading .textbox {
+ width: 100%;
+ min-width: 300px;
+}
+eval-box-wrapped .heading .buttons {
+ position: absolute;
+ top: 0;
+ right: 0px;
+}
+eval-box-wrapped.historyExpr,
+eval-box-wrapped .historyValue {
+ vertical-align: text-top;
+ font: 400 14px 'Montserrat', sans-serif;
+}
+eval-box-wrapped .historyExpr button {
+ display: block;
+ color: black;
+ border: none;
+ background: none;
+ text-decoration: none;
+ padding: 6px 6px;
+ cursor: pointer;
+ white-space: pre-line;
+}
+eval-box-wrapped .historyExpr button:hover {
+ background-color: #fff3e3;
+}
+eval-box-wrapped .historyValue {
+ display: block;
+ padding: 6px 6px;
+}
+eval-box-wrapped .historyDelete button {
+ border: none;
+ background: none;
+}
+eval-box-wrapped .historyDelete button:hover {
+ color: #BB3311;
+}
+
/* flag-list */
flag-list .comment {
@@ -801,12 +914,10 @@
/* heap-snapshot */
-
heap-snapshot .statusMessage {
font-size: 150%;
font-weight: bold;
}
-
heap-snapshot .statusBox {
height: 100%;
padding: 1em;
@@ -973,6 +1084,8 @@
isolate-shared-summary,
isolate-shared-summary-wrapped {
display: block;
+}
+isolate-shared-summary-wrapped > .summary {
height: 300px;
position: relative;
}
@@ -1020,6 +1133,21 @@
color: white;
}
+/* megamorphic-cache-ref */
+/* TODO(cbernaschina) fix megamorphic-cache-ref-wrapped to megamorphic-cache-ref
+when wrapper removed */
+
+megamorphic-cache-ref-wrapped > a[href]:hover {
+ text-decoration: underline;
+}
+megamorphic-cache-ref-wrapped > a[href] {
+ color: #0489c3;
+ text-decoration: none;
+}
+megamorphic-cache-ref-wrapped > a[href] * {
+ color: inherit;
+}
+
/* nav-notify */
/* TODO(cbernaschina) fix nav-notify-wrapped to nav-notify when wrapper
removed */
@@ -1151,6 +1279,12 @@
color: inherit;
}
+/* object-pool-view */
+
+object-pool-view .hexadecimal {
+ font-family: monospace;
+}
+
/* observatory-application */
observatory-application {
@@ -1163,6 +1297,69 @@
height: 100%;
}
+/* persistent-handles-page */
+
+persistent-handles-page {
+ display: block;
+ height: 100%;
+}
+persistent-handles-page .persistent-handles,
+persistent-handles-page .weak-persistent-handles {
+ margin-top: -70px;
+ padding-top: 70px;
+ height: 50%;
+}
+persistent-handles-page virtual-collection {
+ overflow-y: scroll;
+}
+persistent-handles-page .weak-item,
+persistent-handles-page .collection-item {
+ box-sizing: border-box;
+ line-height: 20px;
+ padding-left: 5%;
+ padding-right: 5%;
+}
+persistent-handles-page .header {
+ box-sizing: border-box;
+ line-height: 20px;
+}
+persistent-handles-page .header .weak-item:last-child {
+ margin-bottom: -3px;
+ border-bottom: solid 1px #AAAAAA;
+}
+persistent-handles-page .weak-item .external-size,
+persistent-handles-page .weak-item .peer,
+persistent-handles-page .weak-item .object {
+ display: inline-block;
+ width: 7em;
+ text-align: right;
+ padding-right: 0.5em;
+ line-height: 20px;
+}
+persistent-handles-page .weak-item .peer {
+ width: 11em;
+ font-family: monospace;
+}
+persistent-handles-page .weak-item .object {
+ text-align: left;
+ width: 25em;
+}
+persistent-handles-page .shifter .weak-item:hover {
+ background-color: #d2e7fe;
+}
+persistent-handles-page .weak-item .finalizer {
+ padding-left: 0.5em;
+}
+persistent-handles-page .weak-item > button,
+persistent-handles-page .weak-item > button:active {
+ background-color: transparent;
+ color: #0489c3;
+ border-style: none;
+}
+persistent-handles-page .weak-item > button:hover {
+ text-decoration: underline;
+}
+
/* ports-page */
ports-page .port-number {
@@ -1242,6 +1439,173 @@
0 2px 5px 0 rgba(0, 0, 0, 0.26);
}
+/* script-inset */
+/* TODO(cbernaschina) fix script-inset-wrapped to script-inset when wrapper
+removed */
+
+script-inset-wrapped {
+ position: relative;
+}
+script-inset-wrapped button.refresh,
+script-inset-wrapped button.toggle-profile {
+ background-color: transparent;
+ padding: 0;
+ margin: 0;
+ border: none;
+ position: absolute;
+ display: inline-block;
+ top: 5px;
+ color: #888888;
+ line-height: 30px;
+}
+script-inset-wrapped button.refresh {
+ right: 5px;
+ font-size: 25px;
+}
+script-inset-wrapped button.toggle-profile {
+ right: 30px;
+ font-size: 20px;
+}
+script-inset-wrapped button.toggle-profile.enabled {
+ color: #BB3322;
+}
+script-inset-wrapped a {
+ color: #0489c3;
+ text-decoration: none;
+}
+script-inset-wrapped a:hover {
+ text-decoration: underline;
+}
+script-inset-wrapped .sourceInset {
+}
+script-inset-wrapped .sourceTable {
+ position: relative;
+ background-color: #f5f5f5;
+ border: 1px solid #ccc;
+ padding: 10px;
+ width: 100%;
+ box-sizing: border-box;
+ overflow-x: scroll;
+}
+script-inset-wrapped .sourceRow {
+ display: flex;
+ flex-direction: row;
+ width: 100%;
+}
+script-inset-wrapped .sourceItem,
+script-inset-wrapped .sourceItemCurrent {
+ vertical-align: top;
+ font: 400 14px consolas, courier, monospace;
+ line-height: 125%;
+ white-space: pre;
+ max-width: 0;
+}
+script-inset-wrapped .currentLine {
+ background-color: #fff;
+}
+script-inset-wrapped .currentCol {
+ background-color: #6cf;
+}
+script-inset-wrapped .hitsCurrent,
+script-inset-wrapped .hitsNone,
+script-inset-wrapped .hitsNotExecuted,
+script-inset-wrapped .hitsExecuted,
+script-inset-wrapped .hitsCompiled,
+script-inset-wrapped .hitsNotCompiled {
+ display: table-cell;
+ vertical-align: top;
+ font: 400 14px consolas, courier, monospace;
+ margin-left: 5px;
+ margin-right: 5px;
+ text-align: right;
+ color: #a8a8a8;
+}
+script-inset-wrapped .hitsCurrent {
+ background-color: #6cf;
+ color: black;
+}
+script-inset-wrapped .hitsNotExecuted {
+ background-color: #faa;
+}
+script-inset-wrapped .hitsExecuted {
+ background-color: #aea;
+}
+script-inset-wrapped .hitsCompiled {
+ background-color: #e0e0e0;
+}
+script-inset-wrapped .hitsNotCompiled {
+ background-color: #f0c5c5;
+}
+script-inset-wrapped .noCopy {}
+script-inset-wrapped .emptyBreakpoint,
+script-inset-wrapped .possibleBreakpoint,
+script-inset-wrapped .busyBreakpoint,
+script-inset-wrapped .unresolvedBreakpoint,
+script-inset-wrapped .resolvedBreakpoint {
+ display: table-cell;
+ vertical-align: top;
+ font: 400 14px consolas, courier, monospace;
+ width: 1em;
+ text-align: center;
+ cursor: pointer;
+}
+script-inset-wrapped .possibleBreakpoint {
+ color: #e0e0e0;
+}
+script-inset-wrapped .possibleBreakpoint:hover {
+ color: white;
+ background-color: #777;
+}
+script-inset-wrapped .busyBreakpoint {
+ color: white;
+ background-color: black;
+ cursor: wait;
+}
+script-inset-wrapped .unresolvedBreakpoint {
+ color: white;
+ background-color: #cac;
+}
+script-inset-wrapped .resolvedBreakpoint {
+ color: white;
+ background-color: #e66;
+}
+script-inset-wrapped .unresolvedBreakAnnotation {
+ color: white;
+ background-color: #cac;
+}
+script-inset-wrapped .resolvedBreakAnnotation {
+ color: white;
+ background-color: #e66;
+}
+script-inset-wrapped .notSourceProfile,
+script-inset-wrapped .noProfile,
+script-inset-wrapped .coldProfile,
+script-inset-wrapped .mediumProfile,
+script-inset-wrapped .hotProfile {
+ display: table-cell;
+ vertical-align: top;
+ font: 400 14px consolas, courier, monospace;
+ width: 4em;
+ text-align: right;
+ cursor: pointer;
+ margin-left: 5px;
+ margin-right: 5px;
+}
+script-inset-wrapped .notSourceProfile {
+}
+script-inset-wrapped .noProfile {
+ background-color: #e0e0e0;
+}
+script-inset-wrapped .coldProfile {
+ background-color: #aea;
+}
+script-inset-wrapped .mediumProfile {
+ background-color: #fe9;
+}
+script-inset-wrapped .hotProfile {
+ background-color: #faa;
+}
+
/* stack-trace-tree-config */
stack-trace-tree-config {
diff --git a/runtime/observatory/lib/src/elements/debugger.html b/runtime/observatory/lib/src/elements/debugger.html
index 42fb892..da96388 100644
--- a/runtime/observatory/lib/src/elements/debugger.html
+++ b/runtime/observatory/lib/src/elements/debugger.html
@@ -1,6 +1,5 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="eval_link.html">
-<link rel="import" href="script_inset.html">
<!-- TODO(turnidge): Use core-icon once core_elements work properly in
devtools -->
diff --git a/runtime/observatory/lib/src/elements/error_ref_wrapper.dart b/runtime/observatory/lib/src/elements/error_ref_wrapper.dart
index 50f8b9a..4b0e7e4 100644
--- a/runtime/observatory/lib/src/elements/error_ref_wrapper.dart
+++ b/runtime/observatory/lib/src/elements/error_ref_wrapper.dart
@@ -51,7 +51,8 @@
error-ref-wrapped > pre {
background-color: #f5f5f5;
border: 1px solid #ccc;
- padding: 10px;
+ padding-left: 10px;
+ padding-right: 10px;
font-family: consolas, courier, monospace;
font-size: 1em;
line-height: 1.2em;
diff --git a/runtime/observatory/lib/src/elements/error_view.dart b/runtime/observatory/lib/src/elements/error_view.dart
index 53582cc..aeb3aa8 100644
--- a/runtime/observatory/lib/src/elements/error_view.dart
+++ b/runtime/observatory/lib/src/elements/error_view.dart
@@ -4,14 +4,93 @@
library error_view_element;
-import 'observatory_element.dart';
-import 'package:polymer/polymer.dart';
-import 'package:observatory/service.dart';
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/nav/bar.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import 'package:observatory/src/elements/nav/top_menu.dart';
+import 'package:observatory/src/elements/view_footer.dart';
-/// Displays an Error ServiceObject.
-@CustomTag('error-view')
-class ErrorViewElement extends ObservatoryElement {
- @published DartError error;
+class ErrorViewElement extends HtmlElement implements Renderable{
+ static const tag = const Tag<ErrorViewElement>('error-view',
+ dependencies: const [NavBarElement.tag,
+ NavTopMenuElement.tag,
+ NavNotifyElement.tag,
+ ViewFooterElement.tag]);
+
+ RenderingScheduler _r;
+
+ Stream<RenderedEvent<ErrorViewElement>> get onRendered =>
+ _r.onRendered;
+
+ M.Error _error;
+ M.NotificationRepository _notifications;
+
+ M.Error get error => _error;
+
+ factory ErrorViewElement(M.NotificationRepository notifications,
+ M.Error error,
+ {RenderingQueue queue}) {
+ assert(error != null);
+ assert(notifications != null);
+ ErrorViewElement e = document.createElement(tag.name);
+ e._r = new RenderingScheduler(e, queue: queue);
+ e._error = error;
+ e._notifications = notifications;
+ return e;
+ }
ErrorViewElement.created() : super.created();
-}
\ No newline at end of file
+
+ @override
+ void attached() {
+ super.attached();
+ _r.enable();
+ }
+
+ @override
+ void detached() {
+ super.detached();
+ children = [];
+ _r.disable(notify: true);
+ }
+
+ void render() {
+ children = [
+ new NavBarElement(queue: _r.queue)
+ ..children = [
+ new NavTopMenuElement(last: true, queue: _r.queue),
+ new NavNotifyElement(_notifications, queue: _r.queue)
+ ],
+ new DivElement()
+ ..classes = ['content-centered']
+ ..children = [
+ new HeadingElement.h1()
+ ..text = 'Error: ${_kindToString(_error.kind)}',
+ new BRElement(),
+ new DivElement()..classes = ['well']
+ ..children = [
+ new PreElement()..text = error.message
+ ]
+ ],
+ new ViewFooterElement(queue: _r.queue)
+ ];
+ }
+
+ static String _kindToString(M.ErrorKind kind) {
+ switch(kind) {
+ case M.ErrorKind.unhandledException:
+ return 'Unhandled Exception';
+ case M.ErrorKind.languageError:
+ return 'Language Error';
+ case M.ErrorKind.internalError:
+ return 'Internal Error';
+ case M.ErrorKind.terminationError:
+ return 'Termination Error';
+ }
+ throw new Exception('Unkown M.ErrorKind ($kind)');
+ }
+}
diff --git a/runtime/observatory/lib/src/elements/error_view.html b/runtime/observatory/lib/src/elements/error_view.html
deleted file mode 100644
index aa40472..0000000
--- a/runtime/observatory/lib/src/elements/error_view.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-
-<polymer-element name="error-view">
- <template>
- <link rel="stylesheet" href="css/shared.css">
- <nav-bar>
- <top-nav-menu last="{{ true }}"></top-nav-menu>
- <nav-notify notifications="{{ app.notifications }}"></nav-notify>
- </nav-bar>
- <div class="content-centered">
- <h1>{{ error.kind }}</h1>
- <br>
- <div class="well">{{ error.message }}</div>
- </div>
- <view-footer></view-footer>
- </template>
-</polymer-element>
-
-<script type="application/dart" src="error_view.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/eval_box.dart b/runtime/observatory/lib/src/elements/eval_box.dart
index c6fd2c5..004d9e0 100644
--- a/runtime/observatory/lib/src/elements/eval_box.dart
+++ b/runtime/observatory/lib/src/elements/eval_box.dart
@@ -4,66 +4,207 @@
library eval_box_element;
-import 'dart:async';
import 'dart:html';
-import 'observatory_element.dart';
-import 'package:polymer/polymer.dart';
+import 'dart:async';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/helpers/any_ref.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/instance_ref.dart';
+class EvalBoxElement extends HtmlElement implements Renderable {
+ static const tag = const Tag<EvalBoxElement>('eval-box-wrapped',
+ dependencies: const [
+ InstanceRefElement.tag
+ ]);
-typedef Future evalType(String text);
+ RenderingScheduler<EvalBoxElement> _r;
+ Stream<RenderedEvent<EvalBoxElement>> get onRendered => _r.onRendered;
-@CustomTag('eval-box')
-class EvalBoxElement extends ObservatoryElement {
- @observable String text;
- @observable String lineMode = "1-line";
- int _exprCount = 0;
+ M.IsolateRef _isolate;
+ M.ObjectRef _context;
+ M.InstanceRepository _instances;
+ M.EvalRepository _eval;
+ final _results = <_ExpressionDescription>[];
+ String _expression = '';
+ bool _multiline;
+ Iterable<String> _quickExpressions;
- @published evalType callback;
- @observable ObservableList results = toObservable([]);
+ M.IsolateRef get isolate => _isolate;
+ M.ObjectRef get context => _context;
- void updateLineMode(Event e, var detail, Node target) {
- lineMode = (e.target as InputElement).value;
- if (lineMode == '1-line' && text != null) {
- text = text.replaceAll('\n', ' ');
- }
- }
-
- void evaluate(Event e, var detail, Node target) {
- // Prevent any form action.
- e.preventDefault();
-
- // Clear the text box.
- var expr = text;
- text = '';
-
- // Use provided callback to eval the expression.
- if (callback != null) {
- var map = toObservable({});
- map['id'] = (_exprCount++).toString();
- map['expr'] = expr;
- results.insert(0, map);
- callback(expr).then((result) {
- map['value'] = result;
- }).catchError((e, st) {
- map['error'] = e.message;
- app.handleException(e, st);
- });
- }
- }
-
- void selectExpr(MouseEvent e) {
- assert(e.target is Element);
- Element targetElement = e.target;
- text = targetElement.getAttribute('expr');
- }
-
- void closeItem(MouseEvent e) {
- assert(e.target is Element);
- Element targetElement = e.target;
- var closeId = targetElement.getAttribute('closeId');
- results.removeWhere((item) => item['id'] == closeId);
+ factory EvalBoxElement(M.IsolateRef isolate, M.ObjectRef context,
+ M.InstanceRepository instances,
+ M.EvalRepository eval,
+ {bool multiline: false,
+ Iterable<String> quickExpressions: const [],
+ RenderingQueue queue}) {
+ assert(isolate != null);
+ assert(context != null);
+ assert(instances != null);
+ assert(eval != null);
+ assert(multiline != null);
+ assert(quickExpressions != null);
+ EvalBoxElement e = document.createElement(tag.name);
+ e._r = new RenderingScheduler(e, queue: queue);
+ e._isolate = isolate;
+ e._context = context;
+ e._instances = instances;
+ e._eval = eval;
+ e._multiline = multiline;
+ e._quickExpressions = new List.unmodifiable(quickExpressions);
+ return e;
}
EvalBoxElement.created() : super.created();
+
+ @override
+ void attached() {
+ super.attached();
+ _r.enable();
+ }
+
+ @override
+ void detached() {
+ super.detached();
+ _r.disable(notify: true);
+ children = [];
+ _results.clear();
+ }
+
+ void render() {
+ children = [
+ new DivElement()..classes = const ['quicks']
+ ..children = _quickExpressions.map((q) =>
+ new ButtonElement()
+ ..text = q
+ ..onClick.listen((_) {
+ _expression = q;
+ _run();
+ })
+ ),
+ new DivElement()..classes = const ['heading']
+ ..children = [
+ new FormElement()
+ ..autocomplete = 'on'
+ ..children = [
+ _multiline ? _createEvalTextArea() : _createEvalTextBox(),
+ new SpanElement()..classes = const ['buttons']
+ ..children = [
+ _createEvalButton(),
+ _createMultilineCheckbox(),
+ new SpanElement()..text = 'multi-line'
+ ]
+ ]
+ ],
+ new TableElement()
+ ..children = _results.reversed.map((result) =>
+ new TableRowElement()
+ ..children = [
+ new TableCellElement()..classes = const ['historyExpr']
+ ..children = [
+ new ButtonElement()..text = result.expression
+ ..onClick.listen((_) {
+ _expression = result.expression;
+ _r.dirty();
+ })
+ ],
+ new TableCellElement()..classes = const ['historyValue']
+ ..children = [
+ result.isPending
+ ? (new SpanElement()..text = 'Pending...')
+ : anyRef(_isolate, result.value, _instances,
+ queue: _r.queue)
+ ],
+ new TableCellElement()..classes = const ['historyDelete']
+ ..children = [
+ new ButtonElement()..text = '✖ Remove'
+ ..onClick.listen((_) {
+ _results.remove(result);
+ _r.dirty();
+ })
+ ]
+ ]).toList()
+ ];
+ }
+
+ TextInputElement _createEvalTextArea() {
+ var area = new TextAreaElement()
+ ..classes = ['textbox']
+ ..placeholder = 'evaluate an expression'
+ ..value = _expression
+ ..onKeyUp
+ .where((e) => e.key == '\n')
+ .listen((e) {
+ e.preventDefault();
+ _run();
+ });
+ area.onInput.listen((e) {
+ _expression = area.value;
+ });
+ return area;
+ }
+
+ TextInputElement _createEvalTextBox() {
+ _expression = (_expression ?? '').split('\n')[0];
+ var textbox = new TextInputElement()
+ ..classes = ['textbox']
+ ..placeholder = 'evaluate an expression'
+ ..value = _expression
+ ..onKeyUp
+ .where((e) => e.key == '\n')
+ .listen((e) {
+ e.preventDefault();
+ _run();
+ });
+ textbox.onInput.listen((e) {
+ _expression = textbox.value;
+ });
+ return textbox;
+ }
+
+ ButtonElement _createEvalButton() {
+ final button = new ButtonElement()
+ ..text = 'evaluate'
+ ..onClick.listen((e) {
+ e.preventDefault();
+ _run();
+ });
+ return button;
+ }
+
+ CheckboxInputElement _createMultilineCheckbox() {
+ final checkbox = new CheckboxInputElement()
+ ..checked = _multiline;
+ checkbox.onClick.listen((e) {
+ e.preventDefault();
+ _multiline = checkbox.checked;
+ _r.dirty();
+ });
+ return checkbox;
+ }
+
+ Future _run() async {
+ if (_expression == null || _expression.isEmpty) return;
+ final expression = _expression;
+ _expression = null;
+ final result = new _ExpressionDescription.pending(expression);
+ _results.add(result);
+ _r.dirty();
+ final index = _results.indexOf(result);
+ _results[index] = new _ExpressionDescription(expression,
+ await _eval.evaluate(_isolate, _context, expression));
+ _r.dirty();
+ }
+}
+
+class _ExpressionDescription {
+ final String expression;
+ final M.ObjectRef value;
+ bool get isPending => value == null;
+
+ _ExpressionDescription(this.expression, this.value);
+ _ExpressionDescription.pending(this.expression)
+ : value = null;
}
diff --git a/runtime/observatory/lib/src/elements/eval_box.html b/runtime/observatory/lib/src/elements/eval_box.html
deleted file mode 100644
index 8f9929f..0000000
--- a/runtime/observatory/lib/src/elements/eval_box.html
+++ /dev/null
@@ -1,115 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-
-<polymer-element name="eval-box">
- <template>
- <style>
- .textbox {
- flex-grow: 1;
- font: 400 16px 'Montserrat', sans-serif;
- }
- .bigtextbox {
- flex-grow: 1;
- font: 400 16px 'Montserrat', sans-serif;
- }
- .button {
- font: 400 16px 'Montserrat', sans-serif;
- margin-left: 0.5em;
- margin-right: 0.5em;
- }
- .radios {
- display: inline;
- padding-right: 30px;
- }
- .radios label{
- padding-left: 10px;
- }
- .historyExpr, .historyValue {
- vertical-align: text-top;
- font: 400 14px 'Montserrat', sans-serif;
- }
- .historyExpr a {
- display: block;
- color: black;
- text-decoration: none;
- padding: 6px 6px;
- cursor: pointer;
- white-space: pre-line;
- }
- .historyExpr a:hover {
- background-color: #fff3e3;
- }
- .historyValue {
- display: block;
- padding: 6px 6px;
- }
- a.boxclose {
- margin-left: 20px;
- valign: top;
- display: block;
- height: 18px;
- width: 18px;
- line-height: 16px;
- border-radius: 9px;
- color: black;
- font-size: 18px;
- cursor: pointer;
- text-align: center;
- }
- a.boxclose:hover {
- background: lightgray;
- }
- </style>
- <form style="display:flex; flex-direction:row; align-items:flex-end">
- <template if="{{ lineMode == '1-line' }}">
- <input class="textbox" type="text" value="{{ text }}">
- </template>
- <template if="{{ lineMode == 'N-line' }}">
- <textarea class="bigtextbox"
- value="{{ text }}"></textarea>
- </template>
-
- <input class="button" type="submit" value="Evaluate" on-click="{{ evaluate }}">
- <div class="radios" on-change="{{ updateLineMode }}">
- <label for="1-line">
- <input type="radio" name="lineMode" value="1-line" checked>
- 1-line
- </label>
- <label for="N-line">
- <input type="radio" name="lineMode" value="N-line">
- N-line
- </label>
- </div>
- </form>
-
- <br>
- <template if="{{ results.isNotEmpty }}">
- <table>
- <tr template repeat="{{ result in results }}">
- <td class="historyExpr">
- <a class="expr" on-click="{{ selectExpr }}"
- expr="{{ result['expr'] }}">{{ result['expr'] }}</a>
- </td>
- <td class="historyValue">
- <template if="{{ result['error'] != null}}">
- <div style="color:red">{{ result['error'] }}</div>
- </template>
- <template if="{{ result['error'] == null}}">
- <template if="{{ result['value'] != null }}">
- <any-service-ref ref="{{ result['value'] }}"></any-service-ref>
- </template>
- <template if="{{ result['value'] == null }}">
- <div style="color:#aaa;cursor:wait;"><pending></div>
- </template>
- </template>
- </td>
- <td>
- <a class="boxclose" on-click="{{ closeItem }}"
- closeId="{{ result['id'] }}">×</a>
- </td>
- </tr>
- </table>
- </template>
- </template>
-</polymer-element>
-
-<script type="application/dart" src="eval_box.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/eval_box_wrapper.dart b/runtime/observatory/lib/src/elements/eval_box_wrapper.dart
new file mode 100644
index 0000000..0bd132b
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/eval_box_wrapper.dart
@@ -0,0 +1,143 @@
+// 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.
+
+import 'dart:html';
+
+import 'package:observatory/app.dart';
+import 'package:observatory/repositories.dart';
+import 'package:observatory/service_html.dart' show HeapObject;
+import 'package:observatory/src/elements/eval_box.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/shims/binding.dart';
+
+@bindable
+class EvalBoxElementWrapper extends HtmlElement {
+ static const binder = const Binder<EvalBoxElementWrapper>(const {
+ 'context': #context
+ });
+
+ static const tag = const Tag<EvalBoxElementWrapper>('eval-box');
+
+ HeapObject _context;
+
+ HeapObject get context => _context;
+
+ void set context(HeapObject value) {
+ _context = value;
+ render();
+ }
+
+ EvalBoxElementWrapper.created() : super.created() {
+ binder.registerCallback(this);
+ createShadowRoot();
+ render();
+ }
+
+ @override
+ void attached() {
+ super.attached();
+ render();
+ }
+
+ void render() {
+ shadowRoot.children = [];
+ if (_context == null) {
+ return;
+ }
+
+ shadowRoot.children = [
+ new StyleElement()
+ ..text = '''
+ eval-box-wrapped a[href]:hover {
+ text-decoration: underline;
+ }
+ eval-box-wrapped a[href] {
+ color: #0489c3;
+ text-decoration: none;
+ }
+ eval-box-wrapped .quicks > button:hover {
+ background-color: transparent;
+ border: none;
+ text-decoration: underline;
+ }
+ eval-box-wrapped .quicks > button {
+ background-color: transparent;
+ border: none;
+ color: #0489c3;
+ padding: 0;
+ margin-right: 1em;
+ text-decoration: none;
+ }
+ eval-box-wrapped .empathize {
+ font-style: italic;
+ }
+ eval-box-wrapped .indent {
+ margin-left: 1.5em;
+ font: 400 14px 'Montserrat', sans-serif;
+ line-height: 150%;
+ }
+ eval-box-wrapped .stackTraceBox {
+ margin-left: 1.5em;
+ background-color: #f5f5f5;
+ border: 1px solid #ccc;
+ padding: 10px;
+ font-family: consolas, courier, monospace;
+ font-size: 12px;
+ white-space: pre;
+ overflow-x: auto;
+ }
+ eval-box-wrapped .heading {
+ line-height: 30px;
+ position: relative;
+ box-sizing: border-box;
+ width: 100%;
+ min-width: 450px;
+ padding-right: 150px;
+ }
+ eval-box-wrapped .heading .textbox {
+ width: 100%;
+ min-width: 300px;
+ }
+ eval-box-wrapped .heading .buttons {
+ position: absolute;
+ top: 0;
+ right: 0px;
+ }
+ eval-box-wrapped.historyExpr,
+ eval-box-wrapped .historyValue {
+ vertical-align: text-top;
+ font: 400 14px 'Montserrat', sans-serif;
+ }
+ eval-box-wrapped .historyExpr button {
+ display: block;
+ color: black;
+ border: none;
+ background: none;
+ text-decoration: none;
+ padding: 6px 6px;
+ cursor: pointer;
+ white-space: pre-line;
+ }
+ eval-box-wrapped .historyExpr button:hover {
+ background-color: #fff3e3;
+ }
+ eval-box-wrapped .historyValue {
+ display: block;
+ padding: 6px 6px;
+ }
+ eval-box-wrapped .historyDelete button {
+ border: none;
+ background: none;
+ }
+ eval-box-wrapped .historyDelete button:hover {
+ color: #BB3311;
+ }
+ ''',
+ new EvalBoxElement(_context.isolate, _context,
+ new InstanceRepository(),
+ new EvalRepository(),
+ queue: ObservatoryApplication.app.queue)
+ ];
+ }
+}
diff --git a/runtime/observatory/lib/src/elements/field_view.dart b/runtime/observatory/lib/src/elements/field_view.dart
index 234336d..991fa24 100644
--- a/runtime/observatory/lib/src/elements/field_view.dart
+++ b/runtime/observatory/lib/src/elements/field_view.dart
@@ -5,16 +5,290 @@
library field_view_element;
import 'dart:async';
-import 'observatory_element.dart';
-import 'package:observatory/service.dart';
-import 'package:polymer/polymer.dart';
+import 'dart:html';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/class_ref.dart';
+import 'package:observatory/src/elements/curly_block.dart';
+import 'package:observatory/src/elements/helpers/any_ref.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/nav/bar.dart';
+import 'package:observatory/src/elements/nav/class_menu.dart';
+import 'package:observatory/src/elements/nav/isolate_menu.dart';
+import 'package:observatory/src/elements/nav/library_menu.dart';
+import 'package:observatory/src/elements/nav/menu.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import 'package:observatory/src/elements/nav/refresh.dart';
+import 'package:observatory/src/elements/nav/top_menu.dart';
+import 'package:observatory/src/elements/nav/vm_menu.dart';
+import 'package:observatory/src/elements/object_common.dart';
+import 'package:observatory/src/elements/script_inset.dart';
+import 'package:observatory/src/elements/source_link.dart';
+import 'package:observatory/src/elements/view_footer.dart';
-@CustomTag('field-view')
-class FieldViewElement extends ObservatoryElement {
- @published Field field;
+class FieldViewElement extends HtmlElement implements Renderable {
+ static const tag = const Tag<FieldViewElement>('field-view',
+ dependencies: const [
+ ClassRefElement.tag,
+ CurlyBlockElement.tag,
+ NavBarElement.tag,
+ NavClassMenuElement.tag,
+ NavLibraryMenuElement.tag,
+ NavTopMenuElement.tag,
+ NavVMMenuElement.tag,
+ NavIsolateMenuElement.tag,
+ NavMenuElement.tag,
+ NavRefreshElement.tag,
+ NavNotifyElement.tag,
+ ObjectCommonElement.tag,
+ ScriptInsetElement.tag,
+ SourceLinkElement.tag,
+ ViewFooterElement.tag
+ ]);
+
+ RenderingScheduler<FieldViewElement> _r;
+
+ Stream<RenderedEvent<FieldViewElement>> get onRendered => _r.onRendered;
+
+ M.VM _vm;
+ M.IsolateRef _isolate;
+ M.EventRepository _events;
+ M.NotificationRepository _notifications;
+ M.Field _field;
+ M.LibraryRef _library;
+ M.FieldRepository _fields;
+ M.ClassRepository _classes;
+ M.RetainedSizeRepository _retainedSizes;
+ M.ReachableSizeRepository _reachableSizes;
+ M.InboundReferencesRepository _references;
+ M.RetainingPathRepository _retainingPaths;
+ M.ScriptRepository _scripts;
+ M.InstanceRepository _instances;
+
+
+ M.VMRef get vm => _vm;
+ M.IsolateRef get isolate => _isolate;
+ M.NotificationRepository get notifications => _notifications;
+ M.Field get field => _field;
+
+ factory FieldViewElement(M.VM vm, M.IsolateRef isolate, M.Field field,
+ M.EventRepository events,
+ M.NotificationRepository notifications,
+ M.FieldRepository fields,
+ M.ClassRepository classes,
+ M.RetainedSizeRepository retainedSizes,
+ M.ReachableSizeRepository reachableSizes,
+ M.InboundReferencesRepository references,
+ M.RetainingPathRepository retainingPaths,
+ M.ScriptRepository scripts,
+ M.InstanceRepository instances,
+ {RenderingQueue queue}) {
+ assert(vm != null);
+ assert(isolate != null);
+ assert(events != null);
+ assert(notifications != null);
+ assert(field != null);
+ assert(fields != null);
+ assert(classes != null);
+ assert(retainedSizes != null);
+ assert(reachableSizes != null);
+ assert(references != null);
+ assert(retainingPaths != null);
+ assert(scripts != null);
+ assert(instances != null);
+ FieldViewElement e = document.createElement(tag.name);
+ e._r = new RenderingScheduler(e, queue: queue);
+ e._vm = vm;
+ e._isolate = isolate;
+ e._events = events;
+ e._notifications = notifications;
+ e._field = field;
+ e._fields = fields;
+ e._classes = classes;
+ e._retainedSizes = retainedSizes;
+ e._reachableSizes = reachableSizes;
+ e._references = references;
+ e._retainingPaths = retainingPaths;
+ e._scripts = scripts;
+ e._instances = instances;
+ if (field.dartOwner is M.LibraryRef) {
+ e._library = field.dartOwner;
+ }
+ return e;
+ }
+
FieldViewElement.created() : super.created();
- Future refresh() {
- return field.reload();
+ @override
+ attached() {
+ super.attached();
+ _r.enable();
+ _refresh();
+ }
+
+ @override
+ detached() {
+ super.detached();
+ _r.disable(notify: true);
+ children = [];
+ }
+
+ void render() {
+ var header = '';
+ if (_field.isStatic) {
+ if (_field.dartOwner is M.ClassRef) {
+ header += 'static ';
+ } else {
+ header += 'top-level ';
+ }
+ }
+ if (_field.isFinal) {
+ header += 'final ';
+ } else if (_field.isConst) {
+ header += 'const ';
+ }
+ if (_field.declaredType.name == 'dynamic'){
+ header += 'var';
+ } else {
+ header += _field.declaredType.name;
+ }
+ children = [
+ new NavBarElement(queue: _r.queue)
+ ..children = _createMenu(),
+ new DivElement()..classes = const ['content-centered-big']
+ ..children = [
+ new HeadingElement.h2()..text = '$header ${field.name}',
+ new HRElement(),
+ new ObjectCommonElement(_isolate, _field, _retainedSizes,
+ _reachableSizes, _references, _retainingPaths,
+ _instances, queue: _r.queue),
+ new BRElement(),
+ new DivElement()..classes = ['memberList']
+ ..children = _createMembers(),
+ new HRElement(),
+ new DivElement()
+ ..children = _field.location == null ? const []
+ : [
+ new ScriptInsetElement(_isolate, _field.location.script,
+ _scripts, _instances, _events,
+ startPos: field.location.tokenPos,
+ endPos: field.location.tokenPos,
+ queue: _r.queue)
+ ],
+ new ViewFooterElement(queue: _r.queue)
+ ]
+ ];
+ }
+
+ List<Element> _createMenu() {
+ final menu = [
+ new NavTopMenuElement(queue: _r.queue),
+ new NavVMMenuElement(_vm, _events, queue: _r.queue),
+ new NavIsolateMenuElement(_isolate, _events, queue: _r.queue)
+ ];
+ if (_library != null) {
+ menu.add(new NavLibraryMenuElement(_isolate, _field.dartOwner,
+ queue: _r.queue));
+ } else if (_field.dartOwner is M.ClassRef) {
+ menu.add(
+ new NavClassMenuElement(_isolate, _field.dartOwner, queue: _r.queue),
+ );
+ }
+ menu.addAll([
+ new NavMenuElement(_field.name, last: true, queue: _r.queue),
+ new NavRefreshElement(queue: _r.queue)
+ ..onRefresh.listen((e) {
+ e.element.disabled = true;
+ _refresh();
+ }),
+ new NavNotifyElement(_notifications, queue: _r.queue)
+ ]);
+ return menu;
+ }
+
+ List<Element> _createMembers() {
+ final members = <Element>[
+ new DivElement()..classes = ['memberItem']
+ ..children = [
+ new DivElement()..classes = ['memberName']
+ ..text = 'owner',
+ new DivElement()..classes = ['memberName']
+ ..children = [
+ _field.dartOwner == null
+ ? (new SpanElement()..text = '...')
+ : anyRef(_isolate, _field.dartOwner, _instances,
+ queue: _r.queue)
+ ]
+ ],
+ new DivElement()..classes = ['memberItem']
+ ..children = [
+ new DivElement()..classes = ['memberName']
+ ..text = 'script',
+ new DivElement()..classes = ['memberName']
+ ..children = [
+ new SourceLinkElement(_isolate, field.location, _scripts,
+ queue: _r.queue)
+ ]
+ ]
+ ];
+ if (!_field.isStatic) {
+ members.add(
+ new DivElement()..classes = ['memberItem']
+ ..title = 'The types observed for this field at runtime. '
+ 'Fields that are observed to have a single type at runtime '
+ 'or to never be null may allow for additional optimization.'
+ ..children = [
+ new DivElement()..classes = ['memberName']
+ ..text = 'observed types',
+ new DivElement()..classes = ['memberName']
+ ..children = _createGuard()
+ ]
+ );
+ }
+ if (_field.staticValue != null) {
+ members.add(
+ new DivElement()..classes = ['memberItem']
+ ..children = [
+ new DivElement()..classes = ['memberName']
+ ..text = 'static value',
+ new DivElement()..classes = ['memberName']
+ ..children = [
+ anyRef(_isolate, _field.staticValue, _instances,
+ queue: _r.queue)
+ ]
+ ]
+ );
+ }
+ return members;
+ }
+
+ List<Element> _createGuard() {
+ final guard = <Element>[];
+ switch (_field.guardClassKind) {
+ case M.GuardClassKind.unknown:
+ guard.add(new SpanElement()..text = 'none');
+ break;
+ case M.GuardClassKind.dynamic:
+ guard.add(new SpanElement()..text = 'various');
+ break;
+ case M.GuardClassKind.single:
+ guard.add(new ClassRefElement(_isolate, _field.guardClass,
+ queue: _r.queue));
+ break;
+ }
+ guard.add(new SpanElement()
+ ..text = _field.guardNullable ? '— null observed' : '— null not observed'
+ );
+ return guard;
+ }
+
+ Future _refresh() async {
+ _field = await _fields.get(_isolate, _field.id);
+ if (_field.dartOwner is M.LibraryRef) {
+ _library = _field.dartOwner;
+ } else if (_field.dartOwner is M.ClassRef) {
+ _library = (await _classes.get(_isolate, _field.dartOwner.id)).library;
+ }
+ _r.dirty();
}
}
diff --git a/runtime/observatory/lib/src/elements/field_view.html b/runtime/observatory/lib/src/elements/field_view.html
deleted file mode 100644
index 1ed32f9..0000000
--- a/runtime/observatory/lib/src/elements/field_view.html
+++ /dev/null
@@ -1,99 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-
-<polymer-element name="field-view">
- <template>
- <link rel="stylesheet" href="css/shared.css">
- <nav-bar>
- <top-nav-menu></top-nav-menu>
- <vm-nav-menu vm="{{ field.isolate.vm }}"></vm-nav-menu>
- <isolate-nav-menu isolate="{{ field.isolate }}"></isolate-nav-menu>
- <library-nav-menu library="{{ field.library }}"></library-nav-menu>
- <template if="{{ field.dartOwner is ServiceClass }}">
- <class-nav-menu cls="{{ field.dartOwner }}"></class-nav-menu>
- </template>
- <nav-menu link="{{ makeLink('/inspect', field) }}" anchor="{{ field.name }}" last="{{ true }}"></nav-menu>
- <nav-refresh callback="{{ refresh }}"></nav-refresh>
- <nav-notify notifications="{{ app.notifications }}"></nav-notify>
- </nav-bar>
-
- <div class="content">
- <h1>
- field
- <template if="{{ field.isStatic }}">static</template>
- <template if="{{ field.isFinal }}">final</template>
- <template if="{{ field.isConst }}">const</template>
- <template if="{{ (field.declaredType.name == 'dynamic' &&
- !field.isFinal && !field.isConst) }}">
- var
- </template>
- <template if="{{ (field.declaredType.name != 'dynamic') }}">
- {{ field.declaredType.name }}
- </template>
- {{ field.name }}
- </h1>
-
- <object-common object="{{ field }}"></object-common>
- <br>
-
- <div class="memberList">
- <div class="memberItem">
- <div class="memberName">owner</div>
- <div class="memberValue">
- <any-service-ref ref="{{ field.dartOwner }}"></any-service-ref>
- </div>
- </div>
- <div class="memberItem">
- <div class="memberName">script</div>
- <div class="memberValue">
- <source-link location="{{ field.location }}"></source-link>
- </div>
- </div>
- <template if="{{ !field.isStatic }}">
- <div class="memberItem"
- title="The types observed for this field at runtime. Fields that are observed to have a single type at runtime or to never be null may allow for additional optimization.">
- <div class="memberName">observed types</div>
- <div class="memberValue">
- <template if="{{ field.guardClass == 'dynamic' }}">
- various
- </template>
- <template if="{{ field.guardClass == 'unknown' }}">
- none
- </template>
- <template if="{{ field.guardClass != null &&
- field.guardClass != 'unknown' &&
- field.guardClass != 'dynamic' }}">
- <class-ref ref="{{ field.guardClass }}"></class-ref>
- <template if="{{ field.guardNullable }}">
- — null observed
- </template>
- <template if="{{ !field.guardNullable }}">
- — null not observed
- </template>
- </template>
- </div>
- </div>
- </template>
- <template if="{{ field.staticValue != null }}">
- <div class="memberItem">
- <div class="memberName">static value</div>
- <div class="memberValue">
- <any-service-ref ref="{{ field.staticValue }}"></any-service-ref>
- </div>
- </div>
- </template>
- </div>
- </div>
-
- <div class="content-centered-big">
- <hr>
- <script-inset script="{{ field.location.script }}"
- startPos="{{ field.location.tokenPos }}"
- endPos="{{ field.location.tokenPos }}">
- </script-inset>
- </div>
-
- <view-footer></view-footer>
- </template>
-</polymer-element>
-
-<script type="application/dart" src="field_view.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/function_view.dart b/runtime/observatory/lib/src/elements/function_view.dart
index 58f206b..76c5360 100644
--- a/runtime/observatory/lib/src/elements/function_view.dart
+++ b/runtime/observatory/lib/src/elements/function_view.dart
@@ -5,17 +5,392 @@
library function_view_element;
import 'dart:async';
-import 'observatory_element.dart';
-import 'package:observatory/service.dart';
+import 'dart:html';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/class_ref.dart';
+import 'package:observatory/src/elements/code_ref.dart';
+import 'package:observatory/src/elements/curly_block.dart';
+import 'package:observatory/src/elements/field_ref.dart';
+import 'package:observatory/src/elements/instance_ref.dart';
+import 'package:observatory/src/elements/helpers/any_ref.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/nav/bar.dart';
+import 'package:observatory/src/elements/nav/class_menu.dart';
+import 'package:observatory/src/elements/nav/isolate_menu.dart';
+import 'package:observatory/src/elements/nav/library_menu.dart';
+import 'package:observatory/src/elements/nav/menu.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import 'package:observatory/src/elements/nav/refresh.dart';
+import 'package:observatory/src/elements/nav/top_menu.dart';
+import 'package:observatory/src/elements/nav/vm_menu.dart';
+import 'package:observatory/src/elements/object_common.dart';
+import 'package:observatory/src/elements/source_inset.dart';
+import 'package:observatory/src/elements/source_link.dart';
+import 'package:observatory/src/elements/view_footer.dart';
-import 'package:polymer/polymer.dart';
+class FunctionViewElement extends HtmlElement implements Renderable {
+ static const tag = const Tag<FunctionViewElement>('function-view',
+ dependencies: const [
+ ClassRefElement.tag,
+ CodeRefElement.tag,
+ CurlyBlockElement.tag,
+ FieldRefElement.tag,
+ InstanceRefElement.tag,
+ NavBarElement.tag,
+ NavClassMenuElement.tag,
+ NavLibraryMenuElement.tag,
+ NavTopMenuElement.tag,
+ NavVMMenuElement.tag,
+ NavIsolateMenuElement.tag,
+ NavMenuElement.tag,
+ NavRefreshElement.tag,
+ NavNotifyElement.tag,
+ ObjectCommonElement.tag,
+ SourceLinkElement.tag,
+ SourceInsetElement.tag,
+ ViewFooterElement.tag
+ ]);
-@CustomTag('function-view')
-class FunctionViewElement extends ObservatoryElement {
- @published ServiceFunction function;
+ RenderingScheduler<FunctionViewElement> _r;
+
+ Stream<RenderedEvent<FunctionViewElement>> get onRendered => _r.onRendered;
+
+ M.VM _vm;
+ M.IsolateRef _isolate;
+ M.EventRepository _events;
+ M.NotificationRepository _notifications;
+ M.Function _function;
+ M.LibraryRef _library;
+ M.FunctionRepository _functions;
+ M.ClassRepository _classes;
+ M.RetainedSizeRepository _retainedSizes;
+ M.ReachableSizeRepository _reachableSizes;
+ M.InboundReferencesRepository _references;
+ M.RetainingPathRepository _retainingPaths;
+ M.ScriptRepository _scripts;
+ M.InstanceRepository _instances;
+
+
+ M.VMRef get vm => _vm;
+ M.IsolateRef get isolate => _isolate;
+ M.NotificationRepository get notifications => _notifications;
+ M.Function get function => _function;
+
+ factory FunctionViewElement(M.VM vm, M.IsolateRef isolate, M.Function function,
+ M.EventRepository events,
+ M.NotificationRepository notifications,
+ M.FunctionRepository functions,
+ M.ClassRepository classes,
+ M.RetainedSizeRepository retainedSizes,
+ M.ReachableSizeRepository reachableSizes,
+ M.InboundReferencesRepository references,
+ M.RetainingPathRepository retainingPaths,
+ M.ScriptRepository scripts,
+ M.InstanceRepository instances,
+ {RenderingQueue queue}) {
+ assert(vm != null);
+ assert(isolate != null);
+ assert(events != null);
+ assert(notifications != null);
+ assert(function != null);
+ assert(functions != null);
+ assert(classes != null);
+ assert(retainedSizes != null);
+ assert(reachableSizes != null);
+ assert(references != null);
+ assert(retainingPaths != null);
+ assert(scripts != null);
+ assert(instances != null);
+ FunctionViewElement e = document.createElement(tag.name);
+ e._r = new RenderingScheduler(e, queue: queue);
+ e._vm = vm;
+ e._isolate = isolate;
+ e._events = events;
+ e._notifications = notifications;
+ e._function = function;
+ e._functions = functions;
+ e._classes = classes;
+ e._retainedSizes = retainedSizes;
+ e._reachableSizes = reachableSizes;
+ e._references = references;
+ e._retainingPaths = retainingPaths;
+ e._scripts = scripts;
+ e._instances = instances;
+ if (function.dartOwner is M.LibraryRef) {
+ e._library = function.dartOwner;
+ }
+ return e;
+ }
+
FunctionViewElement.created() : super.created();
- Future refresh() {
- return function.reload();
+ @override
+ attached() {
+ super.attached();
+ _r.enable();
+ _refresh();
+ }
+
+ @override
+ detached() {
+ super.detached();
+ _r.disable(notify: true);
+ children = [];
+ }
+
+ void render() {
+ children = [
+ new NavBarElement(queue: _r.queue)
+ ..children = _createMenu(),
+ new DivElement()..classes = const ['content-centered-big']
+ ..children = [
+ new HeadingElement.h2()..text = 'Function ${_function.name}',
+ new HRElement(),
+ new ObjectCommonElement(_isolate, _function, _retainedSizes,
+ _reachableSizes, _references, _retainingPaths,
+ _instances, queue: _r.queue),
+ new BRElement(),
+ new DivElement()..classes = ['memberList']
+ ..children = _createMembers(),
+ new HRElement(),
+ new DivElement()
+ ..children = _function.location == null ? const []
+ : [
+ new SourceInsetElement(_isolate, _function.location, _scripts,
+ _instances, _events, queue: _r.queue)
+ ],
+ new ViewFooterElement(queue: _r.queue)
+ ]
+ ];
+ }
+
+ List<Element> _createMenu() {
+ final menu = [
+ new NavTopMenuElement(queue: _r.queue),
+ new NavVMMenuElement(_vm, _events, queue: _r.queue),
+ new NavIsolateMenuElement(_isolate, _events, queue: _r.queue)
+ ];
+ if (_library != null) {
+ menu.add(new NavLibraryMenuElement(_isolate, _function.dartOwner,
+ queue: _r.queue));
+ } else if (_function.dartOwner is M.ClassRef) {
+ menu.add(
+ new NavClassMenuElement(_isolate, _function.dartOwner, queue: _r.queue)
+ );
+ }
+ menu.addAll([
+ new NavMenuElement(_function.name, last: true, queue: _r.queue),
+ new NavRefreshElement(queue: _r.queue)
+ ..onRefresh.listen((e) {
+ e.element.disabled = true;
+ _refresh();
+ }),
+ new NavNotifyElement(_notifications, queue: _r.queue)
+ ]);
+ return menu;
+ }
+
+ List<Element> _createMembers() {
+ final members = <Element>[
+ new DivElement()..classes = ['memberItem']
+ ..children = [
+ new DivElement()..classes = ['memberName']
+ ..text = 'kind',
+ new DivElement()..classes = ['memberName']
+ ..children = [
+ new SpanElement()
+ ..text = '${_function.isStatic ? "static ": ""}'
+ '${_function.isConst ? "const ": ""}'
+ '${_functionKindToString(_function.kind)}'
+ ]
+ ],
+ new DivElement()..classes = ['memberItem']
+ ..children = [
+ new DivElement()..classes = ['memberName']
+ ..text = 'owner',
+ new DivElement()..classes = ['memberName']
+ ..children = [
+ _function.dartOwner == null
+ ? (new SpanElement()..text = '...')
+ : anyRef(_isolate, _function.dartOwner, _instances,
+ queue: _r.queue)
+ ]
+ ]
+ ];
+ if (_function.field != null) {
+ members.add(
+ new DivElement()..classes = ['memberItem']
+ ..children = [
+ new DivElement()..classes = ['memberName']
+ ..text = 'script',
+ new DivElement()..classes = ['memberName']
+ ..children = [
+ new FieldRefElement(_isolate, _function.field, _instances,
+ queue: _r.queue)
+ ]
+ ]
+ );
+ }
+ members.add(
+ new DivElement()..classes = ['memberItem']
+ ..children = [
+ new DivElement()..classes = ['memberName']
+ ..text = 'script',
+ new DivElement()..classes = ['memberName']
+ ..children = [
+ new SourceLinkElement(_isolate, _function.location, _scripts,
+ queue: _r.queue)
+ ]
+ ]
+ );
+ if (_function.code != null) {
+ members.add(
+ new DivElement()..classes = ['memberItem']
+ ..children = [
+ new DivElement()..classes = ['memberName']
+ ..text = 'current code',
+ new DivElement()..classes = ['memberName']
+ ..children = [
+ new CodeRefElement(_isolate, _function.code, queue: _r.queue)
+ ]
+ ]
+ );
+ }
+ if (_function.unoptimizedCode != null) {
+ members.add(
+ new DivElement()..classes = ['memberItem']
+ ..children = [
+ new DivElement()..classes = ['memberName']
+ ..text = 'unoptimized code',
+ new DivElement()..classes = ['memberName']
+ ..children = [
+ new CodeRefElement(_isolate, _function.unoptimizedCode,
+ queue: _r.queue),
+ new SpanElement()
+ ..title = 'This count is used to determine when a function '
+ 'will be optimized. It is a combination of call '
+ 'counts and other factors.'
+ ..text = ' (usage count: ${function.usageCounter })'
+ ]
+ ]
+ );
+ }
+ members.addAll([
+ new DivElement()..classes = ['memberItem']
+ ..text = ' ',
+ new DivElement()..classes = ['memberItem']
+ ..children = [
+ new DivElement()..classes = ['memberName']
+ ..text = 'ic data array',
+ new DivElement()..classes = ['memberName']
+ ..children = [
+ new InstanceRefElement(_isolate, _function.icDataArray,
+ _instances, queue: _r.queue)
+ ]
+ ],
+ new DivElement()..classes = ['memberItem']
+ ..children = [
+ new DivElement()..classes = ['memberName']
+ ..text = 'deoptimizations',
+ new DivElement()..classes = ['memberName']
+ ..text = '${_function.deoptimizations}'
+ ],
+ new DivElement()..classes = ['memberItem']
+ ..children = [
+ new DivElement()..classes = ['memberName']
+ ..text = 'optimizable',
+ new DivElement()..classes = ['memberName']
+ ..text = _function.isOptimizable ? 'yes' : 'no'
+ ],
+ new DivElement()..classes = ['memberItem']
+ ..children = [
+ new DivElement()..classes = ['memberName']
+ ..text = 'inlinable',
+ new DivElement()..classes = ['memberName']
+ ..text = _function.isInlinable ? 'yes' : 'no'
+ ],
+ new DivElement()..classes = ['memberItem']
+ ..children = [
+ new DivElement()..classes = ['memberName']
+ ..text = 'intrinsic',
+ new DivElement()..classes = ['memberName']
+ ..text = _function.hasIntrinsic ? 'yes' : 'no'
+ ],
+ new DivElement()..classes = ['memberItem']
+ ..children = [
+ new DivElement()..classes = ['memberName']
+ ..text = 'recognized',
+ new DivElement()..classes = ['memberName']
+ ..text = _function.isRecognized ? 'yes' : 'no'
+ ],
+ new DivElement()..classes = ['memberItem']
+ ..children = [
+ new DivElement()..classes = ['memberName']
+ ..text = 'native',
+ new DivElement()..classes = ['memberName']
+ ..text = _function.isNative ? 'yes' : 'no'
+ ],
+ new DivElement()..classes = ['memberItem']
+ ..children = [
+ new DivElement()..classes = ['memberName']
+ ..text = 'vm name',
+ new DivElement()..classes = ['memberName']
+ ..text = _function.vmName
+ ]
+ ]);
+ return members;
+ }
+
+ Future _refresh() async {
+ _function = await _functions.get(_isolate, _function.id);
+ if (_function.dartOwner is M.LibraryRef) {
+ _library = _function.dartOwner;
+ } else if (_function.dartOwner is M.ClassRef) {
+ _library = (await _classes.get(_isolate, _function.dartOwner.id)).library;
+ }
+ _r.dirty();
+ }
+
+ static String _functionKindToString(M.FunctionKind kind) {
+ switch(kind) {
+ case M.FunctionKind.regular:
+ return 'regular';
+ case M.FunctionKind.closure:
+ return 'closure';
+ case M.FunctionKind.getter:
+ return 'getter';
+ case M.FunctionKind.setter:
+ return 'setter';
+ case M.FunctionKind.constructor:
+ return 'constructor';
+ case M.FunctionKind.implicitGetter:
+ return 'implicit getter';
+ case M.FunctionKind.implicitSetter:
+ return 'implicit setter';
+ case M.FunctionKind.implicitStaticFinalGetter:
+ return 'implicit static final getter';
+ case M.FunctionKind.irregexpFunction:
+ return 'irregexp function';
+ case M.FunctionKind.staticInitializer:
+ return 'static initializer';
+ case M.FunctionKind.methodExtractor:
+ return 'method extractor';
+ case M.FunctionKind.noSuchMethodDispatcher:
+ return 'noSuchMethod dispatcher';
+ case M.FunctionKind.invokeFieldDispatcher:
+ return 'invokeField dispatcher';
+ case M.FunctionKind.collected:
+ return 'collected';
+ case M.FunctionKind.native:
+ return 'native';
+ case M.FunctionKind.stub:
+ return 'stub';
+ case M.FunctionKind.tag:
+ return 'tag';
+ case M.FunctionKind.signatureFunction:
+ return 'signature function';
+ }
+ throw new Exception('Unknown Functionkind ($kind)');
}
}
diff --git a/runtime/observatory/lib/src/elements/function_view.html b/runtime/observatory/lib/src/elements/function_view.html
deleted file mode 100644
index a196455..0000000
--- a/runtime/observatory/lib/src/elements/function_view.html
+++ /dev/null
@@ -1,127 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="script_inset.html">
-
-<polymer-element name="function-view">
- <template>
- <link rel="stylesheet" href="css/shared.css">
- <nav-bar>
- <top-nav-menu></top-nav-menu>
- <vm-nav-menu vm="{{ function.isolate.vm }}"></vm-nav-menu>
- <isolate-nav-menu isolate="{{ function.isolate }}"></isolate-nav-menu>
- <library-nav-menu library="{{ function.library }}"></library-nav-menu>
- <template if="{{ function.dartOwner is ServiceClass }}">
- <class-nav-menu cls="{{ function.dartOwner }}"></class-nav-menu>
- </template>
- <nav-menu link="{{ makeLink('/inspect', function) }}" anchor="{{ function.name }}" last="{{ true }}"></nav-menu>
- <nav-refresh callback="{{ refresh }}"></nav-refresh>
- <nav-notify notifications="{{ app.notifications }}"></nav-notify>
- </nav-bar>
-
- <div class="content">
- <h1>function {{ function.qualifiedName }}</h1>
-
- <object-common object="{{ function }}"></object-common>
- <br>
-
- <div class="memberList">
- <div class="memberItem">
- <div class="memberName">kind</div>
- <div class="memberValue">
- <template if="{{ function.isStatic }}">static</template>
- <template if="{{ function.isConst }}">const</template>
- {{ function.kind.toString() }}
- </div>
- </div>
- <div class="memberItem">
- <div class="memberName">owner</div>
- <div class="memberValue">
- <any-service-ref ref="{{ function.dartOwner }}"></any-service-ref>
- </div>
- </div>
- <template if="{{ function.field != null }}">
- <div class="memberItem">
- <div class="memberName">field</div>
- <div class="memberValue">
- <any-service-ref ref="{{ function.field }}"></any-service-ref>
- </div>
- </div>
- </template>
- <div class="memberItem">
- <div class="memberName">script</div>
- <div class="memberValue">
- <source-link location="{{ function.location }}"></source-link>
- </div>
- </div>
-
- <div class="memberItem"> </div>
-
- <template if="{{ function.code != null }}">
- <div class="memberItem">
- <div class="memberName">current code</div>
- <div class="memberValue">
- <code-ref ref="{{ function.code }}"></code-ref>
- </div>
- </div>
- </template>
- <template if="{{ function.unoptimizedCode != null }}">
- <div class="memberItem">
- <div class="memberName">unoptimized code</div>
- <div class="memberValue">
- <code-ref ref="{{ function.unoptimizedCode }}"></code-ref>
- </div>
- <div class="memberValue">
- <span title="This count is used to determine when a function will be optimized. It is a combination of call counts and other factors.">
- (usage count: {{ function.usageCounter }})
- </span>
- </div>
- </div>
- </template>
- <div class="memberItem">
- <div class="memberName">ic data array</div>
- <div class="memberValue">
- <instance-ref ref="{{ function.icDataArray }}"></instance-ref>
- </div>
- </div>
- <div class="memberItem">
- <div class="memberName">deoptimizations</div>
- <div class="memberValue">{{ function.deoptimizations }}</div>
- </div>
- <div class="memberItem">
- <div class="memberName">optimizable</div>
- <div class="memberValue">{{ function.isOptimizable }}</div>
- </div>
- <div class="memberItem">
- <div class="memberName">inlinable</div>
- <div class="memberValue">{{ function.isInlinable }}</div>
- </div>
- <div class="memberItem">
- <div class="memberName">intrinsic</div>
- <div class="memberValue">{{ function.hasIntrinsic }}</div>
- </div>
- <div class="memberItem">
- <div class="memberName">recognized</div>
- <div class="memberValue">{{ function.isRecognized }}</div>
- </div>
- <div class="memberItem">
- <div class="memberName">native</div>
- <div class="memberValue">{{ function.isNative }}</div>
- </div>
- <template if="{{ function.name != function.vmName }}">
- <div class="memberItem">
- <div class="memberName">vm name</div>
- <div class="memberValue">{{ function.vmName }}</div>
- </div>
- </template>
- </div>
- </div>
-
- <div class="content-centered-big">
- <hr>
- <source-inset location="{{ function.location }}"></source-inset>
- </div>
-
- <view-footer></view-footer>
- </template>
-</polymer-element>
-
-<script type="application/dart" src="function_view.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/heap_map.dart b/runtime/observatory/lib/src/elements/heap_map.dart
index a91e316..1797239 100644
--- a/runtime/observatory/lib/src/elements/heap_map.dart
+++ b/runtime/observatory/lib/src/elements/heap_map.dart
@@ -7,10 +7,284 @@
import 'dart:async';
import 'dart:html';
import 'dart:math';
-import 'observatory_element.dart';
-import 'package:observatory/service.dart';
-import 'package:logging/logging.dart';
-import 'package:polymer/polymer.dart';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/service.dart' as S;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
+import 'package:observatory/src/elements/nav/bar.dart';
+import 'package:observatory/src/elements/nav/isolate_menu.dart';
+import 'package:observatory/src/elements/nav/menu.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import 'package:observatory/src/elements/nav/refresh.dart';
+import 'package:observatory/src/elements/nav/top_menu.dart';
+import 'package:observatory/src/elements/nav/vm_menu.dart';
+class HeapMapElement extends HtmlElement implements Renderable {
+ static const tag = const Tag<HeapMapElement>('heap-map',
+ dependencies: const [
+ NavBarElement.tag,
+ NavTopMenuElement.tag,
+ NavVMMenuElement.tag,
+ NavIsolateMenuElement.tag,
+ NavMenuElement.tag,
+ NavRefreshElement.tag,
+ NavNotifyElement.tag,
+ ]);
+
+ RenderingScheduler<HeapMapElement> _r;
+
+ Stream<RenderedEvent<HeapMapElement>> get onRendered =>
+ _r.onRendered;
+
+ M.VM _vm;
+ M.IsolateRef _isolate;
+ M.EventRepository _events;
+ M.NotificationRepository _notifications;
+ M.VMRef get vm => _vm;
+ M.IsolateRef get isolate => _isolate;
+ M.NotificationRepository get notifications => _notifications;
+
+ factory HeapMapElement(M.VM vm, M.IsolateRef isolate,
+ M.EventRepository events,
+ M.NotificationRepository notifications,
+ {RenderingQueue queue}) {
+ assert(vm != null);
+ assert(isolate != null);
+ assert(events != null);
+ assert(notifications != null);
+ HeapMapElement e = document.createElement(tag.name);
+ e._r = new RenderingScheduler(e, queue: queue);
+ e._vm = vm;
+ e._isolate = isolate;
+ e._events = events;
+ e._notifications = notifications;
+ return e;
+ }
+
+ HeapMapElement.created() : super.created();
+
+ @override
+ attached() {
+ super.attached();
+ _r.enable();
+ _refresh();
+ }
+
+ @override
+ detached() {
+ super.detached();
+ _r.disable(notify: true);
+ children = [];
+ }
+
+ CanvasElement _canvas;
+ var _fragmentationData;
+ double _pageHeight;
+ final _classIdToColor = {};
+ final _colorToClassId = {};
+ final _classIdToName = {};
+
+ static final _freeColor = [255, 255, 255, 255];
+ static final _pageSeparationColor = [0, 0, 0, 255];
+ static const _PAGE_SEPARATION_HEIGHT = 4;
+ // Many browsers will not display a very tall canvas.
+ // TODO(koda): Improve interface for huge heaps.
+ static const _MAX_CANVAS_HEIGHT = 6000;
+
+ String _status;
+ S.ServiceMap _fragmentation;
+
+ void render() {
+ if (_canvas == null) {
+ _canvas = new CanvasElement()
+ ..width = 1
+ ..height= 1
+ ..onMouseMove.listen(_handleMouseMove)
+ ..onMouseDown.listen(_handleClick);
+ }
+ children = [
+ new NavBarElement(queue: _r.queue)
+ ..children = [
+ new NavTopMenuElement(queue: _r.queue),
+ new NavVMMenuElement(_vm, _events, queue: _r.queue),
+ new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+ new NavMenuElement('heap map', last: true,
+ link: Uris.heapMap(_isolate), queue: _r.queue),
+ new NavRefreshElement(queue: _r.queue)
+ ..onRefresh.listen((_) => _refresh()),
+ new NavNotifyElement(_notifications, queue: _r.queue)
+ ],
+ new DivElement()..classes = const ['content-centered-big']
+ ..children = [
+ new HeadingElement.h2()..text = _status,
+ new HRElement(),
+ ],
+ new DivElement()..classes = ['flex-row']
+ ..children = [_canvas]
+ ];
+ }
+
+ // Encode color as single integer, to enable using it as a map key.
+ int _packColor(Iterable<int> color) {
+ int packed = 0;
+ for (var component in color) {
+ packed = packed * 256 + component;
+ }
+ return packed;
+ }
+
+ void _addClass(int classId, String name, Iterable<int> color) {
+ _classIdToName[classId] = name.split('@')[0];
+ _classIdToColor[classId] = color;
+ _colorToClassId[_packColor(color)] = classId;
+ }
+
+ void _updateClassList(classList, int freeClassId) {
+ for (var member in classList['classes']) {
+ if (member is! S.Class) {
+ // TODO(turnidge): The printing for some of these non-class
+ // members is broken. Fix this:
+ //
+ // Logger.root.info('$member');
+ print('Ignoring non-class in class list');
+ continue;
+ }
+ var classId = int.parse(member.id.split('/').last);
+ var color = _classIdToRGBA(classId);
+ _addClass(classId, member.name, color);
+ }
+ _addClass(freeClassId, 'Free', _freeColor);
+ _addClass(0, '', _pageSeparationColor);
+ }
+
+ Iterable<int> _classIdToRGBA(int classId) {
+ // TODO(koda): Pick random hue, but fixed saturation and value.
+ var rng = new Random(classId);
+ return [rng.nextInt(128), rng.nextInt(128), rng.nextInt(128), 255];
+ }
+
+ String _classNameAt(Point<int> point) {
+ var color = new PixelReference(_fragmentationData, point).color;
+ return _classIdToName[_colorToClassId[_packColor(color)]];
+ }
+
+ ObjectInfo _objectAt(Point<int> point) {
+ if (_fragmentation == null || _canvas == null) {
+ return null;
+ }
+ var pagePixels = _pageHeight * _fragmentationData.width;
+ var index = new PixelReference(_fragmentationData, point).index;
+ var pageIndex = index ~/ pagePixels;
+ var pageOffset = index % pagePixels;
+ var pages = _fragmentation['pages'];
+ if (pageIndex < 0 || pageIndex >= pages.length) {
+ return null;
+ }
+ // Scan the page to find start and size.
+ var page = pages[pageIndex];
+ var objects = page['objects'];
+ var offset = 0;
+ var size = 0;
+ for (var i = 0; i < objects.length; i += 2) {
+ size = objects[i];
+ offset += size;
+ if (offset > pageOffset) {
+ pageOffset = offset - size;
+ break;
+ }
+ }
+ return new ObjectInfo(int.parse(page['objectStart']) +
+ pageOffset * _fragmentation['unitSizeBytes'],
+ size * _fragmentation['unitSizeBytes']);
+ }
+
+ void _handleMouseMove(MouseEvent event) {
+ var info = _objectAt(event.offset);
+ if (info == null) {
+ _status = '';
+ _r.dirty();
+ return;
+ }
+ var addressString = '${info.size}B @ 0x${info.address.toRadixString(16)}';
+ var className = _classNameAt(event.offset);
+ _status = (className == '') ? '-' : '$className $addressString';
+ _r.dirty();
+ }
+
+ void _handleClick(MouseEvent event) {
+ final isolate = _isolate as S.Isolate;
+ final address = _objectAt(event.offset).address.toRadixString(16);
+ isolate.getObjectByAddress(address).then((result) {
+ if (result.type != 'Sentinel') {
+ new AnchorElement(
+ href: Uris.inspect(_isolate, object: result as S.HeapObject)
+ ).click();
+ }
+ });
+ }
+
+ void _updateFragmentationData() {
+ if (_fragmentation == null || _canvas == null) {
+ return;
+ }
+ _updateClassList(
+ _fragmentation['classList'], _fragmentation['freeClassId']);
+ var pages = _fragmentation['pages'];
+ var width = _canvas.parent.client.width;
+ _pageHeight = _PAGE_SEPARATION_HEIGHT +
+ _fragmentation['pageSizeBytes'] ~/
+ _fragmentation['unitSizeBytes'] ~/ width;
+ var height = min(_pageHeight * pages.length, _MAX_CANVAS_HEIGHT);
+ _fragmentationData =
+ _canvas.context2D.createImageData(width, height);
+ _canvas.width = _fragmentationData.width;
+ _canvas.height = _fragmentationData.height;
+ _renderPages(0);
+ }
+
+ // Renders and draws asynchronously, one page at a time to avoid
+ // blocking the UI.
+ void _renderPages(int startPage) {
+ var pages = _fragmentation['pages'];
+ _status = 'Loaded $startPage of ${pages.length} pages';
+ _r.dirty();
+ var startY = startPage * _pageHeight;
+ var endY = startY + _pageHeight;
+ if (startPage >= pages.length || endY > _fragmentationData.height) {
+ return;
+ }
+ var pixel = new PixelReference(_fragmentationData, new Point(0, startY));
+ var objects = pages[startPage]['objects'];
+ for (var i = 0; i < objects.length; i += 2) {
+ var count = objects[i];
+ var classId = objects[i + 1];
+ var color = _classIdToColor[classId];
+ while (count-- > 0) {
+ pixel.color = color;
+ pixel = pixel.next();
+ }
+ }
+ while (pixel.point.y < endY) {
+ pixel.color = _pageSeparationColor;
+ pixel = pixel.next();
+ }
+ _canvas.context2D.putImageData(
+ _fragmentationData, 0, 0, 0, startY, _fragmentationData.width, endY);
+ // Continue with the next page, asynchronously.
+ new Future(() {
+ _renderPages(startPage + 1);
+ });
+ }
+
+ Future _refresh() {
+ final isolate = _isolate as S.Isolate;
+ return isolate.invokeRpc('_getHeapMap', {}).then((S.ServiceMap response) {
+ assert(response['type'] == 'HeapMap');
+ _fragmentation = response;
+ _updateFragmentationData();
+ });
+ }
+}
// A reference to a particular pixel of ImageData.
class PixelReference {
@@ -48,211 +322,3 @@
final size;
ObjectInfo(this.address, this.size);
}
-
-@CustomTag('heap-map')
-class HeapMapElement extends ObservatoryElement {
- CanvasElement _fragmentationCanvas;
- var _fragmentationData;
- var _pageHeight;
- var _classIdToColor = {};
- var _colorToClassId = {};
- var _classIdToName = {};
-
- static final _freeColor = [255, 255, 255, 255];
- static final _pageSeparationColor = [0, 0, 0, 255];
- static const _PAGE_SEPARATION_HEIGHT = 4;
- // Many browsers will not display a very tall canvas.
- // TODO(koda): Improve interface for huge heaps.
- static const _MAX_CANVAS_HEIGHT = 6000;
-
- @observable String status;
- @published Isolate isolate;
- @observable ServiceMap fragmentation;
-
- HeapMapElement.created() : super.created() {
- }
-
- @override
- void attached() {
- super.attached();
- _fragmentationCanvas = shadowRoot.querySelector("#fragmentation");
- _fragmentationCanvas.onMouseMove.listen(_handleMouseMove);
- _fragmentationCanvas.onMouseDown.listen(_handleClick);
- }
-
- // Encode color as single integer, to enable using it as a map key.
- int _packColor(Iterable<int> color) {
- int packed = 0;
- for (var component in color) {
- packed = packed * 256 + component;
- }
- return packed;
- }
-
- void _addClass(int classId, String name, Iterable<int> color) {
- _classIdToName[classId] = name.split('@')[0];
- _classIdToColor[classId] = color;
- _colorToClassId[_packColor(color)] = classId;
- }
-
- void _updateClassList(classList, int freeClassId) {
- for (var member in classList['classes']) {
- if (member is! Class) {
- // TODO(turnidge): The printing for some of these non-class
- // members is broken. Fix this:
- //
- // Logger.root.info('$member');
- Logger.root.info('Ignoring non-class in class list');
- continue;
- }
- var classId = int.parse(member.id.split('/').last);
- var color = _classIdToRGBA(classId);
- _addClass(classId, member.name, color);
- }
- _addClass(freeClassId, 'Free', _freeColor);
- _addClass(0, '', _pageSeparationColor);
- }
-
- Iterable<int> _classIdToRGBA(int classId) {
- // TODO(koda): Pick random hue, but fixed saturation and value.
- var rng = new Random(classId);
- return [rng.nextInt(128), rng.nextInt(128), rng.nextInt(128), 255];
- }
-
- String _classNameAt(Point<int> point) {
- var color = new PixelReference(_fragmentationData, point).color;
- return _classIdToName[_colorToClassId[_packColor(color)]];
- }
-
- ObjectInfo _objectAt(Point<int> point) {
- if (fragmentation == null || _fragmentationCanvas == null) {
- return null;
- }
- var pagePixels = _pageHeight * _fragmentationData.width;
- var index = new PixelReference(_fragmentationData, point).index;
- var pageIndex = index ~/ pagePixels;
- var pageOffset = index % pagePixels;
- var pages = fragmentation['pages'];
- if (pageIndex < 0 || pageIndex >= pages.length) {
- return null;
- }
- // Scan the page to find start and size.
- var page = pages[pageIndex];
- var objects = page['objects'];
- var offset = 0;
- var size = 0;
- for (var i = 0; i < objects.length; i += 2) {
- size = objects[i];
- offset += size;
- if (offset > pageOffset) {
- pageOffset = offset - size;
- break;
- }
- }
- return new ObjectInfo(int.parse(page['objectStart']) +
- pageOffset * fragmentation['unitSizeBytes'],
- size * fragmentation['unitSizeBytes']);
- }
-
- void _handleMouseMove(MouseEvent event) {
- var info = _objectAt(event.offset);
- if (info == null) {
- status = '';
- return;
- }
- var addressString = '${info.size}B @ 0x${info.address.toRadixString(16)}';
- var className = _classNameAt(event.offset);
- status = (className == '') ? '-' : '$className $addressString';
- }
-
- void _handleClick(MouseEvent event) {
- var address = _objectAt(event.offset).address.toRadixString(16);
- isolate.getObjectByAddress(address).then((result) {
- if (result.type != 'Sentinel') {
- app.locationManager.go(gotoLink('/inspect', result));
- }
- });
- }
-
- void _updateFragmentationData() {
- if (fragmentation == null || _fragmentationCanvas == null) {
- return;
- }
- _updateClassList(
- fragmentation['classList'], fragmentation['freeClassId']);
- var pages = fragmentation['pages'];
- var width = _fragmentationCanvas.parent.client.width;
- _pageHeight = _PAGE_SEPARATION_HEIGHT +
- fragmentation['pageSizeBytes'] ~/
- fragmentation['unitSizeBytes'] ~/ width;
- var height = min(_pageHeight * pages.length, _MAX_CANVAS_HEIGHT);
- _fragmentationData =
- _fragmentationCanvas.context2D.createImageData(width, height);
- _fragmentationCanvas.width = _fragmentationData.width;
- _fragmentationCanvas.height = _fragmentationData.height;
- _renderPages(0);
- }
-
- // Renders and draws asynchronously, one page at a time to avoid
- // blocking the UI.
- void _renderPages(int startPage) {
- var pages = fragmentation['pages'];
- status = 'Loaded $startPage of ${pages.length} pages';
- var startY = startPage * _pageHeight;
- var endY = startY + _pageHeight;
- if (startPage >= pages.length || endY > _fragmentationData.height) {
- return;
- }
- var pixel = new PixelReference(_fragmentationData, new Point(0, startY));
- var objects = pages[startPage]['objects'];
- for (var i = 0; i < objects.length; i += 2) {
- var count = objects[i];
- var classId = objects[i + 1];
- var color = _classIdToColor[classId];
- while (count-- > 0) {
- pixel.color = color;
- pixel = pixel.next();
- }
- }
- while (pixel.point.y < endY) {
- pixel.color = _pageSeparationColor;
- pixel = pixel.next();
- }
- _fragmentationCanvas.context2D.putImageData(
- _fragmentationData, 0, 0, 0, startY, _fragmentationData.width, endY);
- // Continue with the next page, asynchronously.
- new Future(() {
- _renderPages(startPage + 1);
- });
- }
-
- void isolateChanged(oldValue) {
- if (isolate == null) {
- fragmentation = null;
- return;
- }
- isolate.invokeRpc('_getHeapMap', {}).then((ServiceMap response) {
- assert(response['type'] == 'HeapMap');
- fragmentation = response;
- }).catchError((e, st) {
- Logger.root.info('$e $st');
- });
- }
-
- Future refresh() {
- if (isolate == null) {
- return new Future.value(null);
- }
- return isolate.invokeRpc('_getHeapMap', {}).then((ServiceMap response) {
- assert(response['type'] == 'HeapMap');
- fragmentation = response;
- });
- }
-
- void fragmentationChanged(oldValue) {
- // Async, in case attached has not yet run (observed in JS version).
- new Future(() {
- _updateFragmentationData();
- });
- }
-}
diff --git a/runtime/observatory/lib/src/elements/heap_map.html b/runtime/observatory/lib/src/elements/heap_map.html
deleted file mode 100644
index d68aed2..0000000
--- a/runtime/observatory/lib/src/elements/heap_map.html
+++ /dev/null
@@ -1,44 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-
-<polymer-element name="heap-map">
-<template>
- <link rel="stylesheet" href="css/shared.css">
- <style>
- .hover {
- position: fixed;
- z-index: 999;
- height: 16px;
- width: 100%;
- background: #ffffff;
- }
- .spacer {
- height: 16px;
- background-color: red;
- }
- #fragmentation {
- width: 100%;
- height: 100%;
- }
- </style>
- <nav-bar pad="{{ false }}">
- <top-nav-menu></top-nav-menu>
- <vm-nav-menu vm="{{ fragmentation.isolate.vm }}"></vm-nav-menu>
- <isolate-nav-menu isolate="{{ fragmentation.isolate }}"></isolate-nav-menu>
- <nav-menu link="{{ makeLink('/heap-map', fragmentation.isolate) }}" anchor="heap map" last="{{ true }}"></nav-menu>
- <nav-refresh callback="{{ refresh }}"></nav-refresh>
- <nav-notify notifications="{{ app.notifications }}"></nav-notify>
- </nav-bar>
- <div class="hover">
- <p style="text-align:center">{{ status }}</p>
- </div>
- <div class="spacer">
- <!-- Make sure no data is covered by hover bar initially -->
- </div>
- <div class="flex-row">
- <canvas id="fragmentation" width="1px" height="1px"></canvas>
- </div>
- <view-footer></view-footer>
-</template>
-</polymer-element>
-
-<script type="application/dart" src="heap_map.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/heap_snapshot.dart b/runtime/observatory/lib/src/elements/heap_snapshot.dart
index 0913e1e..e0771eb 100644
--- a/runtime/observatory/lib/src/elements/heap_snapshot.dart
+++ b/runtime/observatory/lib/src/elements/heap_snapshot.dart
@@ -111,7 +111,7 @@
new NavTopMenuElement(queue: _r.queue),
new NavVMMenuElement(_vm, _events, queue: _r.queue),
new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
- new NavMenuElement('heap snapshot', link: Uris.profiler(_isolate),
+ new NavMenuElement('heap snapshot', link: Uris.heapSnapshot(_isolate),
last: true, queue: _r.queue),
new NavRefreshElement(queue: _r.queue)
..disabled = M.isHeapSnapshotProgressRunning(_progress?.status)
diff --git a/runtime/observatory/lib/src/elements/helpers/any_ref.dart b/runtime/observatory/lib/src/elements/helpers/any_ref.dart
index 285b476..56e2ff8 100644
--- a/runtime/observatory/lib/src/elements/helpers/any_ref.dart
+++ b/runtime/observatory/lib/src/elements/helpers/any_ref.dart
@@ -23,8 +23,8 @@
import 'package:observatory/src/elements/token_stream_ref.dart';
import 'package:observatory/src/elements/unknown_ref.dart';
-Element anyRef(M.IsolateRef isolate, ref, M.InstanceRepository instances,
- {RenderingQueue queue}) {
+Element anyRef(M.IsolateRef isolate, ref,
+ M.InstanceRepository instances, {RenderingQueue queue}) {
if (ref is M.Guarded) {
return anyRef(isolate, ref.asSentinel ?? ref.asValue, instances,
queue: queue);
diff --git a/runtime/observatory/lib/src/elements/helpers/uris.dart b/runtime/observatory/lib/src/elements/helpers/uris.dart
index b243f78..05ec28a 100644
--- a/runtime/observatory/lib/src/elements/helpers/uris.dart
+++ b/runtime/observatory/lib/src/elements/helpers/uris.dart
@@ -42,8 +42,6 @@
=> _isolatePage('/persistent-handles', isolate);
static String ports(M.IsolateRef isolate)
=> _isolatePage('/ports', isolate);
- static String profiler(M.IsolateRef isolate)
- => _isolatePage('/profiler', isolate);
static String vm() => '#/vm';
static String vmConnect() => '#/vm-connect';
}
diff --git a/runtime/observatory/lib/src/elements/instance_view.html b/runtime/observatory/lib/src/elements/instance_view.html
index b7c9e13..0673496 100644
--- a/runtime/observatory/lib/src/elements/instance_view.html
+++ b/runtime/observatory/lib/src/elements/instance_view.html
@@ -1,6 +1,4 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="error_view.html">
-<link rel="import" href="eval_box.html">
<link rel="import" href="eval_link.html">
<polymer-element name="instance-view">
@@ -17,355 +15,349 @@
<nav-notify notifications="{{ app.notifications }}"></nav-notify>
</nav-bar>
- <template if="{{ instance.isError }}">
- <error-view error_obj="{{ instance['error'] }}"></error-view>
- </template>
+ <div class="content">
+ <template if="{{ instance.isAbstractType }}">
+ <h1>type {{ instance.name }}</h1>
+ </template>
+ <template if="{{ !instance.isAbstractType }}">
+ <h1>instance of {{ instance.clazz.name }}</h1>
+ </template>
- <template if="{{ !instance.isError }}">
- <div class="content">
- <template if="{{ instance.isAbstractType }}">
- <h1>type {{ instance.name }}</h1>
- </template>
- <template if="{{ !instance.isAbstractType }}">
- <h1>instance of {{ instance.clazz.name }}</h1>
- </template>
+ <object-common object="{{ instance }}"></object-common>
- <object-common object="{{ instance }}"></object-common>
+ <div class="memberList">
+ <div class="memberItem"> </div>
- <div class="memberList">
- <div class="memberItem"> </div>
-
- <template if="{{ instance.valueAsString != null }}">
- <div class="memberItem">
- <div class="memberName">value</div>
- <div class="memberValue">
- <pre>{{ instance.valueAsString }}</pre>
- </div>
- </div>
- </template>
-
- <template if="{{ instance.isString }}">
- <div class="memberItem">
- <div class="memberName">valueAsLiteral</div>
- <div class="memberValue"> {{ asStringLiteral(instance.valueAsString, instance.valueAsStringIsTruncated) }}</div>
- </div>
- </template>
-
- <template if="{{ instance.typeClass != null }}">
- <div class="memberItem">
- <div class="memberName">type class</div>
- <div class="memberValue">
- <class-ref ref="{{ instance.typeClass }}">
- </class-ref>
- </div>
- </div>
- </template>
- <template if="{{ instance.typeArguments.length > 0 }}">
- <div class="memberItem">
- <div class="memberName">type arguments</div>
- <div class="memberValue">
- <
- <template repeat="{{ index in instance.typeArguments['types'].asMap().keys }}">
- <instance-ref ref="{{ instance.typeArguments['types'][index] }}">
- </instance-ref>
- <template if="{{ index < instance.typeArguments['types'].length - 1 }}">
- ,
- </template>
- </template>
- >
- </div>
- </div>
- </template>
- <template if="{{ instance.parameterizedClass != null }}">
- <div class="memberItem">
- <div class="memberName">parameterized class</div>
- <div class="memberValue">
- <class-ref ref="{{ instance.parameterizedClass }}">
- </class-ref>
- </div>
- </div>
- </template>
- <template if="{{ instance.parameterIndex != null }}">
- <div class="memberItem">
- <div class="memberName">parameter index</div>
- <div class="memberValue">
- {{ instance.parameterIndex }}
- </div>
- </div>
- </template>
- <template if="{{ instance.targetType != null }}">
- <div class="memberItem">
- <div class="memberName">target type</div>
- <div class="memberValue">
- <instance-ref ref="{{ instance.targetType }}">
- </instance-ref>
- </div>
- </div>
- </template>
- <template if="{{ instance.bound != null }}">
- <div class="memberItem">
- <div class="memberName">bound</div>
- <div class="memberValue">
- <instance-ref ref="{{ instance.bound }}">
- </instance-ref>
- </div>
- </div>
- </template>
-
- <template if="{{ instance.isClosure }}">
- <div class="memberItem">
- <div class="memberName">closure function</div>
- <div class="memberValue">
- <function-ref ref="{{ instance.closureFunction }}">
- </function-ref>
- </div>
- </div>
- <div class="memberItem">
- <div class="memberName">closure context</div>
- <div class="memberValue">
- <any-service-ref ref="{{ instance.context }}">
- </any-service-ref>
- </div>
- </div>
- <div class="memberItem">
- <div class="memberName">closure breakpoint</div>
- <div class="memberValue">
- <template if="{{ instance.activationBreakpoint == null }}">
- <action-link callback="{{ setBreakOnActivation }}"
- label="break on activation">
- </action-link>
- </template>
- <template if="{{ instance.activationBreakpoint != null }}">
- {{ instance.activationBreakpoint.toString() }}
- <action-link callback="{{ clearBreakOnActivation }}"
- label="remove">
- </action-link>
- </template>
- </div>
- </div>
- </template>
-
- <div class="memberItem">
- <div class="memberName">toString()</div>
- <div class="memberValue">
- <eval-link callback="{{ evaluate }}" expr="toString()"></eval-link>
- </div>
- </div>
- <div class="memberItem">
- <div class="memberName">runtimeType</div>
- <div class="memberValue">
- <eval-link callback="{{ evaluate }}" expr="runtimeType"></eval-link>
- </div>
- </div>
- </div>
- </div>
-
- <hr>
-
- <div class="content">
- <eval-box callback="{{ evaluate }}"></eval-box>
- </div>
-
- <hr>
-
- <div class="content">
- <template if="{{ instance.nativeFields.isNotEmpty }}">
- native fields ({{ instance.nativeFields.length }})
- <curly-block expand="{{ instance.nativeFields.length <= 100 }}">
- <div class="memberList">
- <template repeat="{{ field in instance.nativeFields }}">
- <div class="memberItem">
- <div class="memberName">[{{ field['index']}}]</div>
- <div class="memberValue">[{{ field['value']}}]</div>
- </div>
- </template>
- </div>
- </curly-block><br><br>
- </template>
-
- <template if="{{ instance.fields.isNotEmpty }}">
- fields ({{ instance.fields.length }})
- <curly-block expand="{{ instance.fields.length <= 100 }}">
- <div class="memberList">
- <template repeat="{{ field in instance.fields }}">
- <div class="memberItem">
- <div class="memberName">
- <field-ref ref="{{ field.decl }}"></field-ref>
- </div>
- <div class="memberValue">
- <any-service-ref ref="{{ field.value }}"></any-service-ref>
- </div>
- </div>
- </template>
- </div>
- </curly-block><br><br>
- </template>
-
- <template if="{{ instance.elements.isNotEmpty }}">
- elements ({{ instance.length }})
- <curly-block expand="{{ instance.elements.length <= 100 }}">
- <div class="memberList">
- <template repeat="{{ index in instance.elements.asMap().keys }}">
- <div class="memberItem">
- <div class="memberName">[{{ index }}]</div>
- <div class="memberValue">
- <any-service-ref ref="{{ instance.elements[index] }}">
- </any-service-ref>
- </div>
- </div>
- </template>
- <template if="{{ instance.length != instance.elements.length }}">
- <div class="memberItem">
- <div class="memberName">...</div>
- <div class="memberValue">
- <em>{{ instance.length - instance.elements.length }} omitted elements</em>
- </div>
- </div>
- </template>
- </div>
- </curly-block><br><br>
- </template>
-
- <template if="{{ instance.associations.isNotEmpty }}">
- associations ({{ instance.length }})
- <curly-block expand="{{ instance.associations.length <= 100 }}">
- <div class="memberList">
- <template repeat="{{ association in instance.associations }}">
- <div class="memberItem">
- <div class="memberValue">
- [<any-service-ref ref="{{ association.key }}"></any-service-ref>]
- </div>
- <div class="memberValue">
- <any-service-ref ref="{{ association.value }}"></any-service-ref>
- </div>
- </div>
- </template>
- <template if="{{ instance.length != instance.associations.length }}">
- <div class="memberItem">
- <div class="memberName">...</div>
- <div class="memberValue">
- <em>{{ instance.length - instance.associations.length }} omitted associations</em>
- </div>
- </div>
- </template>
- </div>
- </curly-block><br><br>
- </template>
-
- <template if="{{ instance.typedElements.isNotEmpty }}">
- elements ({{ instance.length }})
- <curly-block expand="{{ instance.typedElements.length <= 100 }}">
- <div class="memberList">
- <template repeat="{{ index in instance.typedElements.asMap().keys }}">
- <div class="memberItem">
- <div class="memberName">[{{ index }}]</div>
- <div class="memberValue">{{ instance.typedElements[index].toString() }}</div>
- </div>
- </template>
- <template if="{{ instance.length != instance.typedElements.length }}">
- <div class="memberItem">
- <div class="memberName">...</div>
- <div class="memberValue">
- <em>{{ instance.length - instance.elements.length }} omitted elements</em>
- </div>
- </div>
- </template>
- </div>
- </curly-block><br><br>
- </template>
-
- <template if="{{ instance.isRegExp }}">
- <div class="memberList">
- <div class="memberItem">
- <div class="memberName">pattern</div>
- <div class="memberValue">
- <any-service-ref ref="{{ instance.pattern }}"></any-service-ref>
- </div>
- </div>
- <div class="memberItem">
- <div class="memberName">isCaseSensitive</div>
- <div class="memberValue">{{ instance.isCaseSensitive }}</div>
- </div>
- <div class="memberItem">
- <div class="memberName">isMultiLine</div>
- <div class="memberValue">{{ instance.isMultiLine }}</div>
- </div>
- <div class="memberItem">
- <div class="memberName">oneByteFunction</div>
- <div class="memberValue">
- <any-service-ref ref="{{ instance.oneByteFunction }}"></any-service-ref>
- </div>
- </div>
- <div class="memberItem">
- <div class="memberName">twoByteFunction</div>
- <div class="memberValue">
- <any-service-ref ref="{{ instance.twoByteFunction }}"></any-service-ref>
- </div>
- </div>
- <div class="memberItem">
- <div class="memberName">externalOneByteFunction</div>
- <div class="memberValue">
- <any-service-ref ref="{{ instance.externalOneByteFunction }}"></any-service-ref>
- </div>
- </div>
- <div class="memberItem">
- <div class="memberName">externalTwoByteFunction</div>
- <div class="memberValue">
- <any-service-ref ref="{{ instance.externalTwoByteFunction }}"></any-service-ref>
- </div>
- </div>
- <div class="memberItem">
- <div class="memberName">oneByteBytecode</div>
- <div class="memberValue">
- <any-service-ref ref="{{ instance.oneByteBytecode }}"></any-service-ref>
- </div>
- </div>
- <div class="memberItem">
- <div class="memberName">twoByteBytecode</div>
- <div class="memberValue">
- <any-service-ref ref="{{ instance.twoByteBytecode }}"></any-service-ref>
- </div>
- </div>
- </div>
- </template>
-
- <template if="{{ instance.isMirrorReference }}">
- <div class="memberItem">
- <div class="memberName">referent</div>
- <div class="memberValue">
- <any-service-ref ref="{{ instance.referent }}">
- </any-service-ref>
- </div>
- </div>
- </template>
-
- <template if="{{ instance.isWeakProperty }}">
- <div class="memberItem">
- <div class="memberName">key</div>
- <div class="memberValue">
- <any-service-ref ref="{{ instance.key }}"></any-service-ref>
- </div>
- </div>
+ <template if="{{ instance.valueAsString != null }}">
<div class="memberItem">
<div class="memberName">value</div>
<div class="memberValue">
- <any-service-ref ref="{{ instance.value }}"></any-service-ref>
+ <pre>{{ instance.valueAsString }}</pre>
</div>
</div>
</template>
- </div>
-
- <div class="content-centered-big">
- <template if="{{ instance.isClosure }}">
- <source-inset location="{{ instance.closureFunction.location }}"></source-inset>
+ <template if="{{ instance.isString }}">
+ <div class="memberItem">
+ <div class="memberName">valueAsLiteral</div>
+ <div class="memberValue"> {{ asStringLiteral(instance.valueAsString, instance.valueAsStringIsTruncated) }}</div>
+ </div>
</template>
+
<template if="{{ instance.typeClass != null }}">
- <source-inset location="{{ instance.typeClass.location }}"></source-inset>
+ <div class="memberItem">
+ <div class="memberName">type class</div>
+ <div class="memberValue">
+ <class-ref ref="{{ instance.typeClass }}">
+ </class-ref>
+ </div>
+ </div>
</template>
- </div>
+ <template if="{{ instance.typeArguments.length > 0 }}">
+ <div class="memberItem">
+ <div class="memberName">type arguments</div>
+ <div class="memberValue">
+ <
+ <template repeat="{{ index in instance.typeArguments['types'].asMap().keys }}">
+ <instance-ref ref="{{ instance.typeArguments['types'][index] }}">
+ </instance-ref>
+ <template if="{{ index < instance.typeArguments['types'].length - 1 }}">
+ ,
+ </template>
+ </template>
+ >
+ </div>
+ </div>
+ </template>
+ <template if="{{ instance.parameterizedClass != null }}">
+ <div class="memberItem">
+ <div class="memberName">parameterized class</div>
+ <div class="memberValue">
+ <class-ref ref="{{ instance.parameterizedClass }}">
+ </class-ref>
+ </div>
+ </div>
+ </template>
+ <template if="{{ instance.parameterIndex != null }}">
+ <div class="memberItem">
+ <div class="memberName">parameter index</div>
+ <div class="memberValue">
+ {{ instance.parameterIndex }}
+ </div>
+ </div>
+ </template>
+ <template if="{{ instance.targetType != null }}">
+ <div class="memberItem">
+ <div class="memberName">target type</div>
+ <div class="memberValue">
+ <instance-ref ref="{{ instance.targetType }}">
+ </instance-ref>
+ </div>
+ </div>
+ </template>
+ <template if="{{ instance.bound != null }}">
+ <div class="memberItem">
+ <div class="memberName">bound</div>
+ <div class="memberValue">
+ <instance-ref ref="{{ instance.bound }}">
+ </instance-ref>
+ </div>
+ </div>
+ </template>
- </template>
+ <template if="{{ instance.isClosure }}">
+ <div class="memberItem">
+ <div class="memberName">closure function</div>
+ <div class="memberValue">
+ <function-ref ref="{{ instance.closureFunction }}">
+ </function-ref>
+ </div>
+ </div>
+ <div class="memberItem">
+ <div class="memberName">closure context</div>
+ <div class="memberValue">
+ <any-service-ref ref="{{ instance.context }}">
+ </any-service-ref>
+ </div>
+ </div>
+ <div class="memberItem">
+ <div class="memberName">closure breakpoint</div>
+ <div class="memberValue">
+ <template if="{{ instance.activationBreakpoint == null }}">
+ <action-link callback="{{ setBreakOnActivation }}"
+ label="break on activation">
+ </action-link>
+ </template>
+ <template if="{{ instance.activationBreakpoint != null }}">
+ {{ instance.activationBreakpoint.toString() }}
+ <action-link callback="{{ clearBreakOnActivation }}"
+ label="remove">
+ </action-link>
+ </template>
+ </div>
+ </div>
+ </template>
+
+ <div class="memberItem">
+ <div class="memberName">toString()</div>
+ <div class="memberValue">
+ <eval-link callback="{{ evaluate }}" expr="toString()"></eval-link>
+ </div>
+ </div>
+ <div class="memberItem">
+ <div class="memberName">runtimeType</div>
+ <div class="memberValue">
+ <eval-link callback="{{ evaluate }}" expr="runtimeType"></eval-link>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <hr>
+
+ <div class="content">
+ <eval-box context="{{ instance }}"></eval-box>
+ </div>
+
+ <hr>
+
+ <div class="content">
+ <template if="{{ instance.nativeFields.isNotEmpty }}">
+ native fields ({{ instance.nativeFields.length }})
+ <curly-block expand="{{ instance.nativeFields.length <= 100 }}">
+ <div class="memberList">
+ <template repeat="{{ field in instance.nativeFields }}">
+ <div class="memberItem">
+ <div class="memberName">[{{ field['index']}}]</div>
+ <div class="memberValue">[{{ field['value']}}]</div>
+ </div>
+ </template>
+ </div>
+ </curly-block><br><br>
+ </template>
+
+ <template if="{{ instance.fields.isNotEmpty }}">
+ fields ({{ instance.fields.length }})
+ <curly-block expand="{{ instance.fields.length <= 100 }}">
+ <div class="memberList">
+ <template repeat="{{ field in instance.fields }}">
+ <div class="memberItem">
+ <div class="memberName">
+ <field-ref ref="{{ field.decl }}"></field-ref>
+ </div>
+ <div class="memberValue">
+ <any-service-ref ref="{{ field.value }}"></any-service-ref>
+ </div>
+ </div>
+ </template>
+ </div>
+ </curly-block><br><br>
+ </template>
+
+ <template if="{{ instance.elements.isNotEmpty }}">
+ elements ({{ instance.length }})
+ <curly-block expand="{{ instance.elements.length <= 100 }}">
+ <div class="memberList">
+ <template repeat="{{ index in instance.elements.asMap().keys }}">
+ <div class="memberItem">
+ <div class="memberName">[{{ index }}]</div>
+ <div class="memberValue">
+ <any-service-ref ref="{{ instance.elements[index] }}">
+ </any-service-ref>
+ </div>
+ </div>
+ </template>
+ <template if="{{ instance.length != instance.elements.length }}">
+ <div class="memberItem">
+ <div class="memberName">...</div>
+ <div class="memberValue">
+ <em>{{ instance.length - instance.elements.length }} omitted elements</em>
+ </div>
+ </div>
+ </template>
+ </div>
+ </curly-block><br><br>
+ </template>
+
+ <template if="{{ instance.associations.isNotEmpty }}">
+ associations ({{ instance.length }})
+ <curly-block expand="{{ instance.associations.length <= 100 }}">
+ <div class="memberList">
+ <template repeat="{{ association in instance.associations }}">
+ <div class="memberItem">
+ <div class="memberValue">
+ [<any-service-ref ref="{{ association.key }}"></any-service-ref>]
+ </div>
+ <div class="memberValue">
+ <any-service-ref ref="{{ association.value }}"></any-service-ref>
+ </div>
+ </div>
+ </template>
+ <template if="{{ instance.length != instance.associations.length }}">
+ <div class="memberItem">
+ <div class="memberName">...</div>
+ <div class="memberValue">
+ <em>{{ instance.length - instance.associations.length }} omitted associations</em>
+ </div>
+ </div>
+ </template>
+ </div>
+ </curly-block><br><br>
+ </template>
+
+ <template if="{{ instance.typedElements.isNotEmpty }}">
+ elements ({{ instance.length }})
+ <curly-block expand="{{ instance.typedElements.length <= 100 }}">
+ <div class="memberList">
+ <template repeat="{{ index in instance.typedElements.asMap().keys }}">
+ <div class="memberItem">
+ <div class="memberName">[{{ index }}]</div>
+ <div class="memberValue">{{ instance.typedElements[index].toString() }}</div>
+ </div>
+ </template>
+ <template if="{{ instance.length != instance.typedElements.length }}">
+ <div class="memberItem">
+ <div class="memberName">...</div>
+ <div class="memberValue">
+ <em>{{ instance.length - instance.elements.length }} omitted elements</em>
+ </div>
+ </div>
+ </template>
+ </div>
+ </curly-block><br><br>
+ </template>
+
+ <template if="{{ instance.isRegExp }}">
+ <div class="memberList">
+ <div class="memberItem">
+ <div class="memberName">pattern</div>
+ <div class="memberValue">
+ <any-service-ref ref="{{ instance.pattern }}"></any-service-ref>
+ </div>
+ </div>
+ <div class="memberItem">
+ <div class="memberName">isCaseSensitive</div>
+ <div class="memberValue">{{ instance.isCaseSensitive }}</div>
+ </div>
+ <div class="memberItem">
+ <div class="memberName">isMultiLine</div>
+ <div class="memberValue">{{ instance.isMultiLine }}</div>
+ </div>
+ <div class="memberItem">
+ <div class="memberName">oneByteFunction</div>
+ <div class="memberValue">
+ <any-service-ref ref="{{ instance.oneByteFunction }}"></any-service-ref>
+ </div>
+ </div>
+ <div class="memberItem">
+ <div class="memberName">twoByteFunction</div>
+ <div class="memberValue">
+ <any-service-ref ref="{{ instance.twoByteFunction }}"></any-service-ref>
+ </div>
+ </div>
+ <div class="memberItem">
+ <div class="memberName">externalOneByteFunction</div>
+ <div class="memberValue">
+ <any-service-ref ref="{{ instance.externalOneByteFunction }}"></any-service-ref>
+ </div>
+ </div>
+ <div class="memberItem">
+ <div class="memberName">externalTwoByteFunction</div>
+ <div class="memberValue">
+ <any-service-ref ref="{{ instance.externalTwoByteFunction }}"></any-service-ref>
+ </div>
+ </div>
+ <div class="memberItem">
+ <div class="memberName">oneByteBytecode</div>
+ <div class="memberValue">
+ <any-service-ref ref="{{ instance.oneByteBytecode }}"></any-service-ref>
+ </div>
+ </div>
+ <div class="memberItem">
+ <div class="memberName">twoByteBytecode</div>
+ <div class="memberValue">
+ <any-service-ref ref="{{ instance.twoByteBytecode }}"></any-service-ref>
+ </div>
+ </div>
+ </div>
+ </template>
+
+ <template if="{{ instance.isMirrorReference }}">
+ <div class="memberItem">
+ <div class="memberName">referent</div>
+ <div class="memberValue">
+ <any-service-ref ref="{{ instance.referent }}">
+ </any-service-ref>
+ </div>
+ </div>
+ </template>
+
+ <template if="{{ instance.isWeakProperty }}">
+ <div class="memberItem">
+ <div class="memberName">key</div>
+ <div class="memberValue">
+ <any-service-ref ref="{{ instance.key }}"></any-service-ref>
+ </div>
+ </div>
+ <div class="memberItem">
+ <div class="memberName">value</div>
+ <div class="memberValue">
+ <any-service-ref ref="{{ instance.value }}"></any-service-ref>
+ </div>
+ </div>
+ </template>
+
+ </div>
+
+ <div class="content-centered-big">
+ <template if="{{ instance.isClosure }}">
+ <source-inset location="{{ instance.closureFunction.location }}"></source-inset>
+ </template>
+ <template if="{{ instance.typeClass != null }}">
+ <source-inset location="{{ instance.typeClass.location }}"></source-inset>
+ </template>
+ </div>
+
<view-footer></view-footer>
</template>
</polymer-element>
diff --git a/runtime/observatory/lib/src/elements/isolate/counter_chart.dart b/runtime/observatory/lib/src/elements/isolate/counter_chart.dart
index 14bc7ef..5f4290e 100644
--- a/runtime/observatory/lib/src/elements/isolate/counter_chart.dart
+++ b/runtime/observatory/lib/src/elements/isolate/counter_chart.dart
@@ -51,11 +51,10 @@
new ChartColumnSpec(label: 'Percent', formatter: (v) => v.toString())
];
- final _series = [new ChartSeries("Work", const [1], new PieChartRenderer(
- sortDataByValue: false
- ))];
-
void render() {
+ final _series = [new ChartSeries("Work", const [1], new PieChartRenderer(
+ sortDataByValue: false
+ ))];
final areaHost = new DivElement()..classes = const ['host'];
final legendHost = new DivElement()..classes = const ['legend'];
children = [areaHost, legendHost];
diff --git a/runtime/observatory/lib/src/elements/isolate/shared_summary.dart b/runtime/observatory/lib/src/elements/isolate/shared_summary.dart
index 51fdc28..91bc2bb 100644
--- a/runtime/observatory/lib/src/elements/isolate/shared_summary.dart
+++ b/runtime/observatory/lib/src/elements/isolate/shared_summary.dart
@@ -50,18 +50,11 @@
}
void render() {
- children = [];
- if (_isolate.error != null) {
- children = [
- new PreElement()..classes = const ["errorBox"]
- ..text = _isolate.error.message
- ];
- }
final newHeapUsed = Utils.formatSize(_isolate.newSpace.used);
final newHeapCapacity = Utils.formatSize(_isolate.newSpace.capacity);
final oldHeapUsed = Utils.formatSize(_isolate.oldSpace.used);
final oldHeapCapacity = Utils.formatSize(_isolate.oldSpace.capacity);
- children.addAll([
+ final content = [
new DivElement()..classes = ['menu']
..children = [
new DivElement()..classes = const ['memberList']
@@ -150,6 +143,19 @@
]
],
new IsolateCounterChartElement(_isolate.counters, queue: _r.queue)
- ]);
+ ];
+ if (_isolate.error != null) {
+ children = [
+ new PreElement()..classes = const ['errorBox']
+ ..text = _isolate.error.message,
+ new DivElement()..classes = const ['summary']
+ ..children = content
+ ];
+ } else {
+ children = [
+ new DivElement()..classes = const ['summary']
+ ..children = content
+ ];
+ }
}
}
diff --git a/runtime/observatory/lib/src/elements/isolate/shared_summary_wrapper.dart b/runtime/observatory/lib/src/elements/isolate/shared_summary_wrapper.dart
index 72b86c2..f51b5f0 100644
--- a/runtime/observatory/lib/src/elements/isolate/shared_summary_wrapper.dart
+++ b/runtime/observatory/lib/src/elements/isolate/shared_summary_wrapper.dart
@@ -88,15 +88,17 @@
}
isolate-shared-summary-wrapped {
display: block;
+ }
+ isolate-shared-summary-wrapped > .summary {
height: 300px;
position: relative;
}
- isolate-shared-summary-wrapped > .menu {
+ isolate-shared-summary-wrapped .menu {
float: right;
top: 0;
right: 0;
}
- isolate-shared-summary-wrapped > isolate-counter-chart {
+ isolate-shared-summary-wrapped isolate-counter-chart {
position: absolute;
left: 0;
top: 0;
diff --git a/runtime/observatory/lib/src/elements/isolate_summary.html b/runtime/observatory/lib/src/elements/isolate_summary.html
index 3c4924d..d34a708 100644
--- a/runtime/observatory/lib/src/elements/isolate_summary.html
+++ b/runtime/observatory/lib/src/elements/isolate_summary.html
@@ -1,6 +1,5 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="action_link.html">
-<link rel="import" href="script_inset.html">
<polymer-element name="isolate-summary">
<template>
diff --git a/runtime/observatory/lib/src/elements/isolate_view.html b/runtime/observatory/lib/src/elements/isolate_view.html
index 16d3150..c03fd22 100644
--- a/runtime/observatory/lib/src/elements/isolate_view.html
+++ b/runtime/observatory/lib/src/elements/isolate_view.html
@@ -1,8 +1,6 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="action_link.html">
-<link rel="import" href="eval_box.html">
<link rel="import" href="isolate_summary.html">
-<link rel="import" href="script_inset.html">
<polymer-element name="isolate-view">
<template>
@@ -126,7 +124,7 @@
<div class="content-centered">
<hr>
- <eval-box callback="{{ evaluate }}"></eval-box>
+ <eval-box context="{{ isolate.rootLibrary }}"></eval-box>
</div>
<div class="content-centered">
diff --git a/runtime/observatory/lib/src/elements/library_view.html b/runtime/observatory/lib/src/elements/library_view.html
index e18e2e6..01eef72 100644
--- a/runtime/observatory/lib/src/elements/library_view.html
+++ b/runtime/observatory/lib/src/elements/library_view.html
@@ -1,5 +1,4 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="eval_box.html">
<polymer-element name="library-view">
<template>
@@ -40,7 +39,7 @@
<hr>
<div class="content">
- <eval-box callback="{{ evaluate }}"></eval-box>
+ <eval-box context="{{ library }}"></eval-box>
</div>
<hr>
diff --git a/runtime/observatory/lib/src/elements/megamorphiccache_view.dart b/runtime/observatory/lib/src/elements/megamorphiccache_view.dart
index 59cb301..817beb1 100644
--- a/runtime/observatory/lib/src/elements/megamorphiccache_view.dart
+++ b/runtime/observatory/lib/src/elements/megamorphiccache_view.dart
@@ -5,17 +5,180 @@
library megamorphiccache_view;
import 'dart:async';
-import 'observatory_element.dart';
-import 'package:observatory/service.dart';
-import 'package:polymer/polymer.dart';
+import 'dart:html';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/context_ref.dart';
+import 'package:observatory/src/elements/curly_block.dart';
+import 'package:observatory/src/elements/helpers/any_ref.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/nav/bar.dart';
+import 'package:observatory/src/elements/nav/isolate_menu.dart';
+import 'package:observatory/src/elements/nav/menu.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import 'package:observatory/src/elements/nav/refresh.dart';
+import 'package:observatory/src/elements/nav/top_menu.dart';
+import 'package:observatory/src/elements/nav/vm_menu.dart';
+import 'package:observatory/src/elements/object_common.dart';
+import 'package:observatory/src/elements/view_footer.dart';
-@CustomTag('megamorphiccache-view')
-class MegamorphicCacheViewElement extends ObservatoryElement {
- @published MegamorphicCache megamorphicCache;
+class MegamorphicCacheViewElement extends HtmlElement implements Renderable {
+ static const tag =
+ const Tag<MegamorphicCacheViewElement>('megamorphiccache-view',
+ dependencies: const [
+ ContextRefElement.tag,
+ CurlyBlockElement.tag,
+ NavBarElement.tag,
+ NavTopMenuElement.tag,
+ NavVMMenuElement.tag,
+ NavIsolateMenuElement.tag,
+ NavMenuElement.tag,
+ NavRefreshElement.tag,
+ NavNotifyElement.tag,
+ ObjectCommonElement.tag,
+ ViewFooterElement.tag
+ ]);
+
+ RenderingScheduler<MegamorphicCacheViewElement> _r;
+
+ Stream<RenderedEvent<MegamorphicCacheViewElement>> get onRendered =>
+ _r.onRendered;
+
+ M.VM _vm;
+ M.IsolateRef _isolate;
+ M.EventRepository _events;
+ M.NotificationRepository _notifications;
+ M.MegamorphicCache _cache;
+ M.MegamorphicCacheRepository _caches;
+ M.RetainedSizeRepository _retainedSizes;
+ M.ReachableSizeRepository _reachableSizes;
+ M.InboundReferencesRepository _references;
+ M.RetainingPathRepository _retainingPaths;
+ M.InstanceRepository _instances;
+
+
+ M.VMRef get vm => _vm;
+ M.IsolateRef get isolate => _isolate;
+ M.NotificationRepository get notifications => _notifications;
+ M.MegamorphicCache get cache => _cache;
+
+ factory MegamorphicCacheViewElement(M.VM vm, M.IsolateRef isolate,
+ M.MegamorphicCache cache,
+ M.EventRepository events,
+ M.NotificationRepository notifications,
+ M.MegamorphicCacheRepository caches,
+ M.RetainedSizeRepository retainedSizes,
+ M.ReachableSizeRepository reachableSizes,
+ M.InboundReferencesRepository references,
+ M.RetainingPathRepository retainingPaths,
+ M.InstanceRepository instances,
+ {RenderingQueue queue}) {
+ assert(vm != null);
+ assert(isolate != null);
+ assert(events != null);
+ assert(notifications != null);
+ assert(cache != null);
+ assert(caches != null);
+ assert(retainedSizes != null);
+ assert(reachableSizes != null);
+ assert(references != null);
+ assert(retainingPaths != null);
+ assert(instances != null);
+ MegamorphicCacheViewElement e = document.createElement(tag.name);
+ e._r = new RenderingScheduler(e, queue: queue);
+ e._vm = vm;
+ e._isolate = isolate;
+ e._events = events;
+ e._notifications = notifications;
+ e._cache = cache;
+ e._caches = caches;
+ e._retainedSizes = retainedSizes;
+ e._reachableSizes = reachableSizes;
+ e._references = references;
+ e._retainingPaths = retainingPaths;
+ e._instances = instances;
+ return e;
+ }
MegamorphicCacheViewElement.created() : super.created();
- Future refresh() {
- return megamorphicCache.reload();
+ @override
+ attached() {
+ super.attached();
+ _r.enable();
+ }
+
+ @override
+ detached() {
+ super.detached();
+ _r.disable(notify: true);
+ children = [];
+ }
+
+ void render() {
+ children = [
+ new NavBarElement(queue: _r.queue)
+ ..children = [
+ new NavTopMenuElement(queue: _r.queue),
+ new NavVMMenuElement(_vm, _events, queue: _r.queue),
+ new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+ new NavMenuElement('object', last: true, queue: _r.queue),
+ new NavRefreshElement(queue: _r.queue)
+ ..onRefresh.listen((e) async {
+ e.element.disabled = true;
+ _cache = await _caches.get(_isolate, _cache.id);
+ _r.dirty();
+ }),
+ new NavNotifyElement(_notifications, queue: _r.queue)
+ ],
+ new DivElement()..classes = const ['content-centered-big']
+ ..children = [
+ new HeadingElement.h2()..text = 'Megamorphic Cache',
+ new HRElement(),
+ new ObjectCommonElement(_isolate, _cache, _retainedSizes,
+ _reachableSizes, _references, _retainingPaths,
+ _instances, queue: _r.queue),
+ new BRElement(),
+ new DivElement()..classes = ['memberList']
+ ..children = [
+ new DivElement()..classes = ['memberItem']
+ ..children = [
+ new DivElement()..classes = ['memberName']
+ ..text = 'selector',
+ new DivElement()..classes = ['memberName']
+ ..text = '${_cache.selector}'
+ ],
+ new DivElement()..classes = ['memberItem']
+ ..children = [
+ new DivElement()..classes = ['memberName']
+ ..text = 'mask',
+ new DivElement()..classes = ['memberName']
+ ..text = '${_cache.mask}'
+ ],
+ new DivElement()..classes = ['memberItem']
+ ..children = [
+ new DivElement()..classes = ['memberName']
+ ..text = 'buckets',
+ new DivElement()..classes = ['memberName']
+ ..children = [
+ anyRef(_isolate, _cache.buckets, _instances,
+ queue: _r.queue)
+ ]
+ ],
+ new DivElement()..classes = ['memberItem']
+ ..children = [
+ new DivElement()..classes = ['memberName']
+ ..text = 'argumentsDescriptor',
+ new DivElement()..classes = ['memberName']
+ ..children = [
+ anyRef(_isolate, _cache.argumentsDescriptor, _instances,
+ queue: _r.queue)
+ ]
+ ]
+ ],
+ new HRElement(),
+ new ViewFooterElement(queue: _r.queue)
+ ]
+ ];
}
}
diff --git a/runtime/observatory/lib/src/elements/megamorphiccache_view.html b/runtime/observatory/lib/src/elements/megamorphiccache_view.html
deleted file mode 100644
index 3f2c804..0000000
--- a/runtime/observatory/lib/src/elements/megamorphiccache_view.html
+++ /dev/null
@@ -1,56 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="error_view.html">
-<link rel="import" href="eval_link.html">
-
-<polymer-element name="megamorphiccache-view">
- <template>
- <link rel="stylesheet" href="css/shared.css">
- <nav-bar>
- <top-nav-menu></top-nav-menu>
- <vm-nav-menu vm="{{ megamorphicCache.isolate.vm }}"></vm-nav-menu>
- <isolate-nav-menu isolate="{{ megamorphicCache.isolate }}"></isolate-nav-menu>
- <nav-menu link="." anchor="object" last="{{ true }}"></nav-menu>
- <nav-refresh callback="{{ refresh }}"></nav-refresh>
- <nav-notify notifications="{{ app.notifications }}"></nav-notify>
- </nav-bar>
-
- <div class="content">
- <object-common object="{{ megamorphicCache }}"></object-common>
-
- <br><br>
-
- <div class="memberList">
- <div class="memberItem">
- <div class="memberName">selector</div>
- <div class="memberValue">
- {{ megamorphicCache.selector }}
- </div>
- </div>
- <div class="memberItem">
- <div class="memberName">argumentsDescriptor</div>
- <div class="memberValue">
- <any-service-ref ref="{{ megamorphicCache.argumentsDescriptor }}"></any-service-ref>
- </div>
- </div>
- <div class="memberItem">
- <div class="memberName">mask</div>
- <div class="memberValue">
- {{ megamorphicCache.mask }}
- </div>
- </div>
- <div class="memberItem">
- <div class="memberName">buckets</div>
- <div class="memberValue">
- <any-service-ref ref="{{ megamorphicCache.buckets }}"></any-service-ref>
- </div>
- </div>
- </div>
-
- </div>
-
- <hr>
- <view-footer></view-footer>
- </template>
-</polymer-element>
-
-<script type="application/dart" src="megamorphiccache_view.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/object_common.dart b/runtime/observatory/lib/src/elements/object_common.dart
index 6426032..f82c7ec 100644
--- a/runtime/observatory/lib/src/elements/object_common.dart
+++ b/runtime/observatory/lib/src/elements/object_common.dart
@@ -102,7 +102,10 @@
..text = 'Class ',
new DivElement()..classes = const ['memberValue']
..children = [
- new ClassRefElement(_isolate, _object.clazz, queue: _r.queue)
+ _object.clazz == null
+ ? (new SpanElement()..text = '...')
+ : new ClassRefElement(_isolate, _object.clazz,
+ queue: _r.queue)
]
],
new DivElement()..classes = const ['memberItem']
diff --git a/runtime/observatory/lib/src/elements/object_view.html b/runtime/observatory/lib/src/elements/object_view.html
index 7092ed5..bc4dd7b 100644
--- a/runtime/observatory/lib/src/elements/object_view.html
+++ b/runtime/observatory/lib/src/elements/object_view.html
@@ -1,5 +1,4 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="error_view.html">
<link rel="import" href="eval_link.html">
<polymer-element name="object-view">
diff --git a/runtime/observatory/lib/src/elements/objectpool_view.dart b/runtime/observatory/lib/src/elements/objectpool_view.dart
index 1e08198..1ba83f2 100644
--- a/runtime/observatory/lib/src/elements/objectpool_view.dart
+++ b/runtime/observatory/lib/src/elements/objectpool_view.dart
@@ -5,19 +5,172 @@
library objectpool_view;
import 'dart:async';
-import 'observatory_element.dart';
-import 'package:observatory/service.dart';
-import 'package:polymer/polymer.dart';
+import 'dart:html';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/context_ref.dart';
+import 'package:observatory/src/elements/curly_block.dart';
+import 'package:observatory/src/elements/helpers/any_ref.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/nav/bar.dart';
+import 'package:observatory/src/elements/nav/isolate_menu.dart';
+import 'package:observatory/src/elements/nav/menu.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import 'package:observatory/src/elements/nav/refresh.dart';
+import 'package:observatory/src/elements/nav/top_menu.dart';
+import 'package:observatory/src/elements/nav/vm_menu.dart';
+import 'package:observatory/src/elements/object_common.dart';
+import 'package:observatory/src/elements/view_footer.dart';
-@CustomTag('objectpool-view')
-class ObjectPoolViewElement extends ObservatoryElement {
- @published ObjectPool pool;
+class ObjectPoolViewElement extends HtmlElement implements Renderable {
+ static const tag = const Tag<ObjectPoolViewElement>('object-pool-view',
+ dependencies: const [
+ ContextRefElement.tag,
+ CurlyBlockElement.tag,
+ NavBarElement.tag,
+ NavTopMenuElement.tag,
+ NavVMMenuElement.tag,
+ NavIsolateMenuElement.tag,
+ NavMenuElement.tag,
+ NavRefreshElement.tag,
+ NavNotifyElement.tag,
+ ObjectCommonElement.tag,
+ ViewFooterElement.tag
+ ]);
+
+ RenderingScheduler<ObjectPoolViewElement> _r;
+
+ Stream<RenderedEvent<ObjectPoolViewElement>> get onRendered => _r.onRendered;
+
+ M.VM _vm;
+ M.IsolateRef _isolate;
+ M.EventRepository _events;
+ M.NotificationRepository _notifications;
+ M.ObjectPool _pool;
+ M.ObjectPoolRepository _pools;
+ M.RetainedSizeRepository _retainedSizes;
+ M.ReachableSizeRepository _reachableSizes;
+ M.InboundReferencesRepository _references;
+ M.RetainingPathRepository _retainingPaths;
+ M.InstanceRepository _instances;
+
+
+ M.VMRef get vm => _vm;
+ M.IsolateRef get isolate => _isolate;
+ M.NotificationRepository get notifications => _notifications;
+ M.ObjectPoolRef get pool => _pool;
+
+ factory ObjectPoolViewElement(M.VM vm, M.IsolateRef isolate,
+ M.ObjectPool pool,
+ M.EventRepository events,
+ M.NotificationRepository notifications,
+ M.ObjectPoolRepository pools,
+ M.RetainedSizeRepository retainedSizes,
+ M.ReachableSizeRepository reachableSizes,
+ M.InboundReferencesRepository references,
+ M.RetainingPathRepository retainingPaths,
+ M.InstanceRepository instances,
+ {RenderingQueue queue}) {
+ assert(vm != null);
+ assert(isolate != null);
+ assert(events != null);
+ assert(notifications != null);
+ assert(pool != null);
+ assert(pools != null);
+ assert(retainedSizes != null);
+ assert(reachableSizes != null);
+ assert(references != null);
+ assert(retainingPaths != null);
+ assert(instances != null);
+ ObjectPoolViewElement e = document.createElement(tag.name);
+ e._r = new RenderingScheduler(e, queue: queue);
+ e._vm = vm;
+ e._isolate = isolate;
+ e._events = events;
+ e._notifications = notifications;
+ e._pool = pool;
+ e._pools = pools;
+ e._retainedSizes = retainedSizes;
+ e._reachableSizes = reachableSizes;
+ e._references = references;
+ e._retainingPaths = retainingPaths;
+ e._instances = instances;
+ return e;
+ }
ObjectPoolViewElement.created() : super.created();
- bool isServiceObject(o) => o is ServiceObject;
+ @override
+ attached() {
+ super.attached();
+ _r.enable();
+ }
- Future refresh() {
- return pool.reload();
+ @override
+ detached() {
+ super.detached();
+ _r.disable(notify: true);
+ children = [];
+ }
+
+ void render() {
+ children = [
+ new NavBarElement(queue: _r.queue)
+ ..children = [
+ new NavTopMenuElement(queue: _r.queue),
+ new NavVMMenuElement(_vm, _events, queue: _r.queue),
+ new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+ new NavMenuElement('instance', last: true, queue: _r.queue),
+ new NavRefreshElement(queue: _r.queue)
+ ..onRefresh.listen((e) async {
+ e.element.disabled = true;
+ _pool = await _pools.get(_isolate, _pool.id);
+ _r.dirty();
+ }),
+ new NavNotifyElement(_notifications, queue: _r.queue)
+ ],
+ new DivElement()..classes = const ['content-centered-big']
+ ..children = [
+ new HeadingElement.h2()..text = 'Object Pool',
+ new HRElement(),
+ new ObjectCommonElement(_isolate, _pool, _retainedSizes,
+ _reachableSizes, _references, _retainingPaths,
+ _instances, queue: _r.queue),
+ new HRElement(),
+ new HeadingElement.h3()..text = 'entries (${_pool.entries.length})',
+ new DivElement()..classes = const ['memberList']
+ ..children = _pool.entries.map((entry)
+ => new DivElement()..classes = const ['memberItem']
+ ..children = [
+ new DivElement()..classes = const ['memberName',
+ 'hexadecimal']
+ ..text = '[PP+0x${entry.offset.toRadixString(16)}]',
+ new DivElement()..classes = const ['memberName']
+ ..children = _createEntry(entry)
+ ]).toList(),
+ new HRElement(),
+ new ViewFooterElement(queue: _r.queue)
+ ]
+ ];
+ }
+
+ List<Element> _createEntry(M.ObjectPoolEntry entry) {
+ switch (entry.kind) {
+ case M.ObjectPoolEntryKind.object:
+ return [
+ anyRef(_isolate, entry.asObject, _instances, queue: _r.queue)
+ ];
+ case M.ObjectPoolEntryKind.immediate:
+ return [
+ new SpanElement()
+ ..text = 'Immediate 0x${entry.asInteger.toRadixString(16)}'
+ ];
+ case M.ObjectPoolEntryKind.nativeEntry:
+ return [
+ new SpanElement()
+ ..text = 'NativeEntry 0x${entry.asInteger.toRadixString(16)}'
+ ];
+ }
+ throw new Exception('Unkown ObjectPoolEntryKind (${entry.kind})');
}
}
diff --git a/runtime/observatory/lib/src/elements/objectpool_view.html b/runtime/observatory/lib/src/elements/objectpool_view.html
deleted file mode 100644
index 555ddb4..0000000
--- a/runtime/observatory/lib/src/elements/objectpool_view.html
+++ /dev/null
@@ -1,50 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="error_view.html">
-<link rel="import" href="eval_link.html">
-
-<polymer-element name="objectpool-view">
- <template>
- <link rel="stylesheet" href="css/shared.css">
- <nav-bar>
- <top-nav-menu></top-nav-menu>
- <vm-nav-menu vm="{{ pool.isolate.vm }}"></vm-nav-menu>
- <isolate-nav-menu isolate="{{ pool.isolate }}"></isolate-nav-menu>
- <nav-menu link="." anchor="object" last="{{ true }}"></nav-menu>
- <nav-refresh callback="{{ refresh }}"></nav-refresh>
- <nav-notify notifications="{{ app.notifications }}"></nav-notify>
- </nav-bar>
-
- <div class="content">
- <object-common object="{{ pool }}"></object-common>
-
- <br><br>
-
- entries ({{ pool.entries.length }})
- <div class="memberList">
- <template repeat="{{ entry in pool.entries }}">
- <div class="memberItem">
- <div class="memberName">[PP+0x{{ entry['offset'].toRadixString(16) }}]</div>
- <div class="memberValue">
- <template if="{{ entry['kind'] == 'Object' }}">
- <any-service-ref ref="{{ entry['value'] }}">
- </any-service-ref>
- </template>
- <template if="{{ entry['kind'] == 'Immediate' }}">
- Immediate 0x{{ entry['value'].toRadixString(16) }}
- </template>
- <template if="{{ entry['kind'] == 'NativeEntry' }}">
- NativeEntry 0x{{ entry['value'].toRadixString(16) }}
- </template>
- </div>
- </div>
- </template>
- </div>
-
- </div>
-
- <hr>
- <view-footer></view-footer>
- </template>
-</polymer-element>
-
-<script type="application/dart" src="objectpool_view.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/objectstore_view.dart b/runtime/observatory/lib/src/elements/objectstore_view.dart
index c5ff3bc..72a1596 100644
--- a/runtime/observatory/lib/src/elements/objectstore_view.dart
+++ b/runtime/observatory/lib/src/elements/objectstore_view.dart
@@ -5,20 +5,131 @@
library objectstore_view_element;
import 'dart:async';
-import 'observatory_element.dart';
-import 'package:observatory/service.dart';
-import 'package:polymer/polymer.dart';
+import 'dart:html';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/helpers/any_ref.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/instance_ref.dart';
+import 'package:observatory/src/elements/nav/bar.dart';
+import 'package:observatory/src/elements/nav/isolate_menu.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import 'package:observatory/src/elements/nav/refresh.dart';
+import 'package:observatory/src/elements/nav/top_menu.dart';
+import 'package:observatory/src/elements/nav/vm_menu.dart';
+import 'package:observatory/src/elements/view_footer.dart';
+
+class ObjectStoreViewElement extends HtmlElement implements Renderable {
+ static const tag = const Tag<ObjectStoreViewElement>('objectstore-view',
+ dependencies: const [
+ InstanceRefElement.tag,
+ NavBarElement.tag,
+ NavTopMenuElement.tag,
+ NavVMMenuElement.tag,
+ NavIsolateMenuElement.tag,
+ NavRefreshElement.tag,
+ NavNotifyElement.tag,
+ ViewFooterElement.tag
+ ]);
+
+ RenderingScheduler<ObjectStoreViewElement> _r;
+
+ Stream<RenderedEvent<ObjectStoreViewElement>> get onRendered => _r.onRendered;
+
+ M.VM _vm;
+ M.IsolateRef _isolate;
+ M.EventRepository _events;
+ M.NotificationRepository _notifications;
+ M.ObjectStore _store;
+ M.ObjectStoreRepository _stores;
+ M.InstanceRepository _instances;
-@CustomTag('objectstore-view')
-class ObjectStoreViewElement extends ObservatoryElement {
- @published ObjectStore objectStore;
+ M.VMRef get vm => _vm;
+ M.IsolateRef get isolate => _isolate;
+ M.NotificationRepository get notifications => _notifications;
+
+ factory ObjectStoreViewElement(M.VM vm, M.IsolateRef isolate,
+ M.EventRepository events,
+ M.NotificationRepository notifications,
+ M.ObjectStoreRepository stores,
+ M.InstanceRepository instances,
+ {RenderingQueue queue}) {
+ assert(vm != null);
+ assert(isolate != null);
+ assert(events != null);
+ assert(notifications != null);
+ assert(stores != null);
+ assert(instances != null);
+ ObjectStoreViewElement e = document.createElement(tag.name);
+ e._r = new RenderingScheduler(e, queue: queue);
+ e._vm = vm;
+ e._isolate = isolate;
+ e._events = events;
+ e._notifications = notifications;
+ e._stores = stores;
+ e._instances = instances;
+ return e;
+ }
ObjectStoreViewElement.created() : super.created();
- Future refresh() {
- return objectStore.isolate.getObjectStore().then((newObjectStore) {
- objectStore = newObjectStore;
- });
+ @override
+ attached() {
+ super.attached();
+ _r.enable();
+ _refresh();
+ }
+
+ @override
+ detached() {
+ super.detached();
+ _r.disable(notify: true);
+ children = [];
+ }
+
+ void render() {
+ final fields = _store?.fields?.toList(growable: false);
+ children = [
+ new NavBarElement(queue: _r.queue)
+ ..children = [
+ new NavTopMenuElement(queue: _r.queue),
+ new NavVMMenuElement(_vm, _events, queue: _r.queue),
+ new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+ new NavRefreshElement(disabled: _store == null, queue: _r.queue)
+ ..onRefresh.listen((e) => _refresh()),
+ new NavNotifyElement(_notifications, queue: _r.queue)
+ ],
+ new DivElement()..classes = const ['content-centered-big']
+ ..children = [
+ new HeadingElement.h1()
+ ..text = fields == null
+ ? 'Object Store'
+ : 'Object Store (${fields.length})',
+ new HRElement(),
+ fields == null
+ ? (new HeadingElement.h2()..text = 'Loading...')
+ : (new DivElement()..classes = const ['memberList']
+ ..children = fields.map((field) =>
+ new DivElement()..classes = const ['memberItem']
+ ..children = [
+ new DivElement()..classes = const ['memberName']
+ ..text = field.name,
+ new DivElement()..classes = const ['memberValue']
+ ..children = [
+ anyRef(_isolate, field.value, _instances,
+ queue: _r.queue)
+ ]
+ ]).toList()),
+ new ViewFooterElement(queue: _r.queue)
+ ]
+ ];
+ }
+
+ Future _refresh() async {
+ _store = null;
+ _r.dirty();
+ _store = await _stores.get(_isolate);
+ _r.dirty();
}
}
diff --git a/runtime/observatory/lib/src/elements/objectstore_view.html b/runtime/observatory/lib/src/elements/objectstore_view.html
deleted file mode 100644
index 1cdeb76..0000000
--- a/runtime/observatory/lib/src/elements/objectstore_view.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="eval_box.html">
-
-<polymer-element name="objectstore-view">
- <template>
- <link rel="stylesheet" href="css/shared.css">
-
- <nav-bar>
- <top-nav-menu></top-nav-menu>
- <vm-nav-menu vm="{{ objectStore.isolate.vm }}"></vm-nav-menu>
- <isolate-nav-menu isolate="{{ objectStore.isolate }}" last="{{ true }}"></isolate-nav-menu>
- <nav-refresh callback="{{ refresh }}"></nav-refresh>
- <nav-notify notifications="{{ app.notifications }}"></nav-notify>
- </nav-bar>
-
- <div class="content-centered-big">
- <h1>
- object store ({{ objectStore.fields.length }})
- </h1>
-
- <hr>
-
- <div class="memberList">
- <template repeat="{{ field in objectStore.fields }}">
- <div class="memberItem">
- <div class="memberName">{{ field.name }}</div>
- <div class="memberValue"><any-service-ref ref="{{ field.value }}"></any-service-ref></div>
- </div>
- </template>
- </div>
- </div>
-
- <view-footer></view-footer>
- </template>
-</polymer-element>
-
-<script type="application/dart" src="library_view.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/observatory_element.dart b/runtime/observatory/lib/src/elements/observatory_element.dart
index a661ccf..ed52cf0 100644
--- a/runtime/observatory/lib/src/elements/observatory_element.dart
+++ b/runtime/observatory/lib/src/elements/observatory_element.dart
@@ -189,35 +189,4 @@
anchorElement.onClick.listen(onClickGoto);
shadowRoot.children.add(anchorElement);
}
-
-
- var _onCopySubscription;
- /// Exclude nodes from being copied, for example the line numbers and
- /// breakpoint toggles in script insets. Must be called after [root]'s
- /// children have been added, and only supports one node at a time.
- void makeCssClassUncopyable(Element root, String className) {
- var noCopyNodes = root.getElementsByClassName(className);
- for (var node in noCopyNodes) {
- node.style.setProperty('-moz-user-select', 'none');
- node.style.setProperty('-khtml-user-select', 'none');
- node.style.setProperty('-webkit-user-select', 'none');
- node.style.setProperty('-ms-user-select', 'none');
- node.style.setProperty('user-select', 'none');
- }
- if (_onCopySubscription != null) {
- _onCopySubscription.cancel();
- }
- _onCopySubscription = root.onCopy.listen((event) {
- // Mark the nodes as hidden before the copy happens, then mark them as
- // visible on the next event loop turn.
- for (var node in noCopyNodes) {
- node.style.visibility = 'hidden';
- }
- Timer.run(() {
- for (var node in noCopyNodes) {
- node.style.visibility = 'visible';
- }
- });
- });
- }
}
diff --git a/runtime/observatory/lib/src/elements/persistent_handles.dart b/runtime/observatory/lib/src/elements/persistent_handles.dart
index f6ccfaf..7a7b333 100644
--- a/runtime/observatory/lib/src/elements/persistent_handles.dart
+++ b/runtime/observatory/lib/src/elements/persistent_handles.dart
@@ -6,173 +6,269 @@
import 'dart:async';
import 'dart:html';
-import 'observatory_element.dart';
-import 'package:observatory/app.dart';
-import 'package:observatory/elements.dart';
-import 'package:observatory/service.dart';
-import 'package:polymer/polymer.dart';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/containers/virtual_collection.dart';
+import 'package:observatory/src/elements/helpers/any_ref.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
+import 'package:observatory/src/elements/instance_ref.dart';
+import 'package:observatory/src/elements/nav/bar.dart';
+import 'package:observatory/src/elements/nav/isolate_menu.dart';
+import 'package:observatory/src/elements/nav/menu.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import 'package:observatory/src/elements/nav/refresh.dart';
+import 'package:observatory/src/elements/nav/top_menu.dart';
+import 'package:observatory/src/elements/nav/vm_menu.dart';
+import 'package:observatory/utils.dart';
-class WeakPersistentHandlesSortedTable extends SortedTable {
- factory WeakPersistentHandlesSortedTable() {
- var columns = [
- new SortedTableColumn.withFormatter('External Size',
- Utils.formatSize),
- new SortedTableColumn('Peer'),
- new SortedTableColumn('Finalizer Callback'),
- new SortedTableColumn(''), // Spacer column.
- new SortedTableColumn('Object'),
- ];
- WeakPersistentHandlesSortedTable result =
- new WeakPersistentHandlesSortedTable._(columns);
- // Sort by external size.
- result.sortColumnIndex = 0;
- return result;
- }
-
- WeakPersistentHandlesSortedTable._(columns) : super(columns);
-
- @override
- dynamic getSortKeyFor(int row, int col) {
- return super.getSortKeyFor(row, col);
- }
-
- void update(List<ServiceMap> handles, HtmlElement tableBody) {
- clearRows();
- for (ServiceMap handle in handles) {
- var row = [int.parse(handle['externalSize'], onError: (_) => 0),
- handle['peer'],
- handle['callbackSymbolName'] +
- '( ${handle['callbackAddress']} )',
- '', // Spacer column.
- handle['object']];
- addRow(new SortedTableRow(row));
- print(row);
- }
- sort();
- _updateTableInDom(tableBody);
- }
-
- void sortAndDisplay(HtmlElement tableBody) {
- sort();
- _updateTableInDom(tableBody);
- }
-
-
- void _updateTableInDom(HtmlElement tableBody) {
- assert(tableBody != null);
- // Resize DOM table.
- if (tableBody.children.length > sortedRows.length) {
- // Shrink the table.
- var deadRows =
- tableBody.children.length - sortedRows.length;
- for (var i = 0; i < deadRows; i++) {
- tableBody.children.removeLast();
- }
- } else if (tableBody.children.length < sortedRows.length) {
- // Grow table.
- var newRows = sortedRows.length - tableBody.children.length;
- for (var i = 0; i < newRows; i++) {
- _addDomRow(tableBody);
- }
- }
- assert(tableBody.children.length == sortedRows.length);
- // Fill table.
- for (var i = 0; i < sortedRows.length; i++) {
- var rowIndex = sortedRows[i];
- var tr = tableBody.children[i];
- _fillDomRow(tr, rowIndex);
- }
- }
-
- void _addDomRow(HtmlElement tableBody) {
- // Add empty dom row.
- var tr = new TableRowElement();
-
- var cell;
-
- cell = tr.insertCell(-1);
- cell = tr.insertCell(-1);
- cell = tr.insertCell(-1);
-
- // Add spacer.
- cell = tr.insertCell(-1);
- cell.classes.add('left-border-spacer');
-
- // Add class ref.
- cell = tr.insertCell(-1);
- AnyServiceRefElement objectRef = new Element.tag('any-service-ref');
- cell.children.add(objectRef);
-
- // Add row to table.
- tableBody.children.add(tr);
- }
-
- void _fillDomRow(TableRowElement tr, int rowIndex) {
- var row = rows[rowIndex];
-
- for (var i = 0; i < row.values.length - 2; i++) {
- var cell = tr.children[i];
- cell.title = row.values[i].toString();
- cell.text = getFormattedValue(rowIndex, i);
- cell.style.paddingLeft = '1em';
- cell.style.paddingRight = '1em';
- }
-
- final int objectIndex = row.values.length - 1;
- AnyServiceRefElement objectRef = tr.children[objectIndex].children[0];
- objectRef.ref = row.values[objectIndex];
- }
+enum _SortingField {
+ externalSize,
+ peer,
+ finalizerCallback
}
+enum _SortingDirection {
+ ascending,
+ descending
+}
-@CustomTag('persistent-handles-page')
-class PersistentHandlesPageElement extends ObservatoryElement {
+class PersistentHandlesPageElement extends HtmlElement implements Renderable {
+ static const tag =
+ const Tag<PersistentHandlesPageElement>('persistent-handles-page',
+ dependencies: const [
+ InstanceRefElement.tag,
+ NavBarElement.tag,
+ NavTopMenuElement.tag,
+ NavVMMenuElement.tag,
+ NavIsolateMenuElement.tag,
+ NavMenuElement.tag,
+ NavRefreshElement.tag,
+ NavNotifyElement.tag,
+ VirtualCollectionElement.tag
+ ]);
+
+ RenderingScheduler<PersistentHandlesPageElement> _r;
+
+ Stream<RenderedEvent<PersistentHandlesPageElement>> get onRendered =>
+ _r.onRendered;
+
+ M.VM _vm;
+ M.IsolateRef _isolate;
+ M.EventRepository _events;
+ M.NotificationRepository _notifications;
+ M.PersistentHandlesRepository _repository;
+ M.InstanceRepository _instances;
+ M.PersistentHandles _handles;
+ _SortingField _sortingField =
+ _SortingField.externalSize;
+ _SortingDirection _sortingDirection =
+ _SortingDirection.descending;
+
+ M.VMRef get vm => _vm;
+ M.IsolateRef get isolate => _isolate;
+ M.NotificationRepository get notifications => _notifications;
+
+ factory PersistentHandlesPageElement(M.VM vm, M.IsolateRef isolate,
+ M.EventRepository events,
+ M.NotificationRepository notifications,
+ M.PersistentHandlesRepository repository,
+ M.InstanceRepository instances,
+ {RenderingQueue queue}) {
+ assert(vm != null);
+ assert(isolate != null);
+ assert(events != null);
+ assert(notifications != null);
+ assert(repository != null);
+ assert(instances != null);
+ PersistentHandlesPageElement e = document.createElement(tag.name);
+ e._r = new RenderingScheduler(e, queue: queue);
+ e._vm = vm;
+ e._isolate = isolate;
+ e._events = events;
+ e._notifications = notifications;
+ e._repository = repository;
+ e._instances = instances;
+ return e;
+ }
+
PersistentHandlesPageElement.created() : super.created();
- @observable Isolate isolate;
- @observable var /*ObservableList | ServiceObject*/ persistentHandles;
- @observable var /*ObservableList | ServiceObject*/ weakPersistentHandles;
- @observable WeakPersistentHandlesSortedTable weakPersistentHandlesTable;
- var _weakPersistentHandlesTableBody;
-
- void isolateChanged(oldValue) {
- if (isolate != null) {
- refresh();
- }
+ @override
+ attached() {
+ super.attached();
+ _r.enable();
+ _refresh();
}
@override
- void attached() {
- super.attached();
- _weakPersistentHandlesTableBody =
- shadowRoot.querySelector('#weakPersistentHandlesTableBody');
- weakPersistentHandlesTable =
- new WeakPersistentHandlesSortedTable();
+ detached() {
+ super.detached();
+ _r.disable(notify: true);
+ children = [];
}
- Future refresh() {
- return isolate.getPersistentHandles().then(_refreshView);
+ void render() {
+ children = [
+ new NavBarElement(queue: _r.queue)
+ ..children = [
+ new NavTopMenuElement(queue: _r.queue),
+ new NavVMMenuElement(_vm, _events, queue: _r.queue),
+ new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+ new NavMenuElement('persistent handles', last: true,
+ link: Uris.persistentHandles(_isolate), queue: _r.queue),
+ new NavRefreshElement(queue: _r.queue)
+ ..onRefresh.listen((_) => _refresh()),
+ new NavNotifyElement(_notifications, queue: _r.queue)
+ ]
+ ]..addAll(_createHandlers('Persistent Handles',
+ _handles?.elements?.toList(),
+ _createLine,
+ _updateLine))
+ ..add(new BRElement())
+ ..addAll(_createHandlers('Weak Persistent Handles',
+ _handles == null
+ ? null
+ : (_handles.weakElements.toList()
+ ..sort(_createSorter())),
+ _createWeakLine,
+ _updateWeakLine,
+ createHeader: _createWeakHeader));
}
- _refreshView(/*ObservableList | ServiceObject*/ object) {
- persistentHandles = object['persistentHandles'];
- weakPersistentHandles = object['weakPersistentHandles'];
- weakPersistentHandlesTable.update(
- weakPersistentHandles,
- _weakPersistentHandlesTableBody);
+ List<Element> _createHandlers(String name, List items, create, update,
+ {createHeader}) {
+ return [
+ new DivElement()..classes = const ['content-centered-big']
+ ..children = [
+ new HeadingElement.h1()
+ ..text = items == null ? '$name'
+ : '$name (${items.length})',
+ new HRElement(),
+ ],
+ new DivElement()..classes = const ['persistent-handles']
+ ..children = [
+ items == null
+ ? (new HeadingElement.h2()..classes = const ['content-centered-big']
+ ..text = 'Loading...')
+ : new VirtualCollectionElement(create, update, items: items,
+ createHeader: createHeader,
+ queue: _r.queue)
+ ]
+ ];
}
- @observable void changeSort(Event e, var detail, Element target) {
- if (target is TableCellElement) {
- if (weakPersistentHandlesTable.sortColumnIndex != target.cellIndex) {
- weakPersistentHandlesTable.sortColumnIndex = target.cellIndex;
- weakPersistentHandlesTable.sortDescending = true;
- } else {
- weakPersistentHandlesTable.sortDescending =
- !weakPersistentHandlesTable.sortDescending;
- }
- weakPersistentHandlesTable.sortAndDisplay(
- _weakPersistentHandlesTableBody);
+ _createSorter() {
+ var getter;
+ switch (_sortingField) {
+ case _SortingField.externalSize:
+ getter = _getExternalSize;
+ break;
+ case _SortingField.peer:
+ getter = _getPeer;
+ break;
+ case _SortingField.finalizerCallback:
+ getter = _getFinalizerCallback;
+ break;
+ }
+ switch (_sortingDirection) {
+ case _SortingDirection.ascending:
+ return (a, b) => getter(a).compareTo(getter(b));
+ case _SortingDirection.descending:
+ return (a, b) => getter(b).compareTo(getter(a));
}
}
+
+ static Element _createLine() =>
+ new DivElement()..classes = const ['collection-item']
+ ..text = 'object';
+
+ static Element _createWeakLine() =>
+ new DivElement()
+ ..classes = const ['weak-item']
+ ..children = [
+ new SpanElement()..classes = const ['external-size']
+ ..text = '0B',
+ new SpanElement()..classes = const ['peer']
+ ..text = '0x00000',
+ new SpanElement()..classes = const ['object'],
+ new SpanElement()..classes = const ['finalizer']
+ ..text = 'dart::Class::Method()'
+ ];
+
+ Element _createWeakHeader() =>
+ new DivElement()
+ ..classes = const ['weak-item']
+ ..children = [
+ _createHeaderButton(const ['external-size'], 'External Size',
+ _SortingField.externalSize,
+ _SortingDirection.descending),
+ _createHeaderButton(const ['peer'], 'Peer',
+ _SortingField.peer,
+ _SortingDirection.descending),
+ new SpanElement()..classes = const ['object']
+ ..text = 'Object',
+ _createHeaderButton(const ['finalizer'], 'Finalizer Callback',
+ _SortingField.finalizerCallback,
+ _SortingDirection.ascending)
+ ];
+
+ ButtonElement _createHeaderButton(List<String> classes,
+ String text,
+ _SortingField field,
+ _SortingDirection direction) =>
+ new ButtonElement()..classes = classes
+ ..text = _sortingField != field ? text :
+ _sortingDirection == _SortingDirection.ascending
+ ? '$textâ–¼' : '$textâ–²'
+ ..onClick.listen((_) => _setSorting(field, direction));
+
+
+ void _setSorting(_SortingField field,
+ _SortingDirection defaultDirection) {
+ if (_sortingField == field) {
+ switch (_sortingDirection) {
+ case _SortingDirection.descending:
+ _sortingDirection = _SortingDirection.ascending;
+ break;
+ case _SortingDirection.ascending:
+ _sortingDirection = _SortingDirection.descending;
+ break;
+ }
+ } else {
+ _sortingDirection = defaultDirection;
+ _sortingField = field;
+ }
+ _r.dirty();
+ }
+
+ void _updateWeakLine(Element e, M.WeakPersistentHandle item,
+ index) {
+ e.children[0].text = Utils.formatSize(_getExternalSize(item));
+ e.children[1].text = '${_getPeer(item)}';
+ e.children[2] = anyRef(_isolate, item.object, _instances, queue: _r.queue)
+ ..classes = const ['object'];
+ e.children[3]..text = '${_getFinalizerCallback(item)}'
+ ..title = '${_getFinalizerCallback(item)}';
+ }
+
+ void _updateLine(Element e, M.PersistentHandle item,
+ index) {
+ e.children = [
+ anyRef(_isolate, item.object, _instances, queue: _r.queue)
+ ..classes = const ['object']
+ ];
+ }
+
+ Future _refresh({bool gc: false, bool reset: false}) async {
+ _handles = null;
+ _r.dirty();
+ _handles = await _repository.get(_isolate);
+ _r.dirty();
+ }
+
+ static int _getExternalSize(M.WeakPersistentHandle h) => h.externalSize;
+ static String _getPeer(M.WeakPersistentHandle h) => h.peer;
+ static String _getFinalizerCallback(M.WeakPersistentHandle h) =>
+ '${h.callbackSymbolName} (${h.callbackAddress})';
}
diff --git a/runtime/observatory/lib/src/elements/persistent_handles.html b/runtime/observatory/lib/src/elements/persistent_handles.html
deleted file mode 100644
index af92aa7..0000000
--- a/runtime/observatory/lib/src/elements/persistent_handles.html
+++ /dev/null
@@ -1,105 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-
-<polymer-element name="persistent-handles-page">
- <template>
- <link rel="stylesheet" href="css/shared.css">
- <style>
- .table {
- border-collapse: collapse!important;
- margin-bottom: 20px
- table-layout: fixed;
- width: 100%;
- }
- .table td:nth-of-type(1) {
- width: 30%;
- }
- .th, .td {
- padding: 8px;
- vertical-align: top;
- }
- .table thead > tr > th {
- vertical-align: bottom;
- text-align: left;
- border-bottom:2px solid #ddd;
- }
- .spacer {
- width: 16px;
- }
- .left-border-spacer {
- width: 16px;
- border-left: 1px solid;
- }
- .clickable {
- color: #0489c3;
- text-decoration: none;
- cursor: pointer;
- }
- .clickable:hover {
- text-decoration: underline;
- cursor: pointer;
- }
- #weakPersistentHandlesTable tr:hover > td {
- background-color: #F4C7C3;
- }
- .nav-option {
- color: white;
- float: right;
- margin: 3px;
- padding: 8px;
- }
- </style>
- <nav-bar>
- <top-nav-menu></top-nav-menu>
- <vm-nav-menu vm="{{ isolate.vm }}"></vm-nav-menu>
- <isolate-nav-menu isolate="{{ isolate }}"></isolate-nav-menu>
- <nav-menu link="{{ makeLink('/persistent-handles', isolate) }}" anchor="persistent handles" last="{{ true }}"></nav-menu>
- <nav-refresh callback="{{ refresh }}"></nav-refresh>
- <nav-notify notifications="{{ app.notifications }}"></nav-notify>
- </nav-bar>
- <div class="content-centered-big">
- <template if="{{ persistentHandles.isEmpty }}">
- <h1>Persistent Handles (0)</h1>
- <hr>
- </template>
- <template if="{{ persistentHandles.isNotEmpty }}">
- <h1>Persistent Handles ({{ persistentHandles.length }})</h1>
- <hr>
- <curly-block expand="{{ persistentHandles.length <= 8 }}">
- <div class="memberList">
- <template repeat="{{ persistentHandle in persistentHandles }}">
- <div class="memberItem">
- <div class="memberValue">
- <any-service-ref ref="{{ persistentHandle['object'] }}">
- </any-service-ref>
- </div>
- </div>
- </template>
- </div>
- </curly-block><br><br>
- </template>
- <br><br>
- <template if="{{ weakPersistentHandles.isEmpty }}">
- <h1>Weak Persistent Handles (0)</h1>
- <hr>
- </template>
- <template if="{{ weakPersistentHandles.isNotEmpty }}">
- <h1>Weak Persistent Handles ({{ weakPersistentHandles.length }})</h1>
- <hr>
- </template>
- <table id="weakPersistentHandlesTable" class="flex-item-100-percent table">
- <thead id="weakPersistentHandlesTableHead">
- <tr>
- <th on-click="{{changeSort}}" class="clickable" title="External Size">{{ weakPersistentHandlesTable.getColumnLabel(0) }}</th>
- <th on-click="{{changeSort}}" class="clickable" title="Peer">{{ weakPersistentHandlesTable.getColumnLabel(1) }}</th>
- <th on-click="{{changeSort}}" class="clickable" title="Finalizer Callback">{{ weakPersistentHandlesTable.getColumnLabel(2) }}</th>
- <th class="spacer"></th>
- <th on-click="{{changeSort}}" class="clickable" title="Object">{{ weakPersistentHandlesTable.getColumnLabel(4) }}</th>
- </tr>
- </thead>
- <tbody id="weakPersistentHandlesTableBody">
- </tbody>
- </table>
- <view-footer></view-footer>
- </div>
- </template>
-</polymer-element>
diff --git a/runtime/observatory/lib/src/elements/script_inset.dart b/runtime/observatory/lib/src/elements/script_inset.dart
index fbbef3a..d968fe0 100644
--- a/runtime/observatory/lib/src/elements/script_inset.dart
+++ b/runtime/observatory/lib/src/elements/script_inset.dart
@@ -6,14 +6,931 @@
import 'dart:async';
import 'dart:html';
-import 'dart:math';
-import 'observatory_element.dart';
-import 'service_ref.dart';
+import 'package:observatory/app.dart';
import 'package:observatory/models.dart' as M;
-import 'package:observatory/service.dart';
+import 'package:observatory/service.dart' as S;
+import 'package:observatory/src/elements/helpers/any_ref.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
import 'package:observatory/utils.dart';
-import 'package:polymer/polymer.dart';
-import 'package:logging/logging.dart';
+
+class ScriptInsetElement extends HtmlElement implements Renderable {
+ static const tag = const Tag<ScriptInsetElement>('script-inset-wrapped');
+
+ RenderingScheduler _r;
+
+ Stream<RenderedEvent<ScriptInsetElement>> get onRendered => _r.onRendered;
+
+
+ M.IsolateRef _isolate;
+ M.ScriptRef _script;
+ M.Script _loadedScript;
+ M.ScriptRepository _scripts;
+ M.InstanceRepository _instances;
+ M.EventRepository _events;
+ StreamSubscription _subscription;
+ int _startPos;
+ int _endPos;
+ int _currentPos;
+ bool _inDebuggerContext;
+ Iterable _variables;
+
+ M.IsolateRef get isolate => _isolate;
+ M.ScriptRef get script => _script;
+
+ factory ScriptInsetElement(M.IsolateRef isolate, M.ScriptRef script,
+ M.ScriptRepository scripts,
+ M.InstanceRepository instances,
+ M.EventRepository events,
+ {int startPos, int endPos, int currentPos,
+ bool inDebuggerContext: false,
+ Iterable variables: const [],
+ RenderingQueue queue}) {
+ assert(isolate != null);
+ assert(script != null);
+ assert(scripts != null);
+ assert(instances != null);
+ assert(events != null);
+ assert(inDebuggerContext != null);
+ assert(variables != null);
+ ScriptInsetElement e = document.createElement(tag.name);
+ e._r = new RenderingScheduler(e, queue: queue);
+ e._isolate = isolate;
+ e._script = script;
+ e._scripts = scripts;
+ e._instances = instances;
+ e._events = events;
+ e._startPos = startPos;
+ e._endPos = endPos;
+ e._currentPos = currentPos;
+ e._inDebuggerContext = inDebuggerContext;
+ e._variables = new List.unmodifiable(variables);
+ return e;
+ }
+
+ ScriptInsetElement.created() : super.created();
+
+ @override
+ void attached() {
+ super.attached();
+ _r.enable();
+ _subscription = _events.onDebugEvent
+ .where((e) => (e is M.BreakpointAddedEvent) ||
+ (e is M.BreakpointResolvedEvent) ||
+ (e is M.BreakpointRemovedEvent))
+ .map((e) => e.breakpoint)
+ .listen((M.Breakpoint b) {
+ final loc = b.location;
+ int line;
+ if (loc.script.id == script.id) {
+ if (loc.tokenPos != null) {
+ line = _loadedScript.tokenToLine(loc.tokenPos);
+ } else {
+ line = loc.line;
+ }
+ } else {
+ line = loc.line;
+ }
+ if ((line == null) || ((line >= _startLine) && (line <= _endLine))) {
+ _r.dirty();
+ }
+ });
+ _refresh();
+ }
+
+ @override
+ void detached() {
+ super.detached();
+ children = [];
+ _r.disable(notify: true);
+ _subscription.cancel();
+ }
+
+ void render() {
+ if (_loadedScript == null) {
+ children = [new SpanElement()..text = 'Loading...'];
+ } else {
+ final table = linesTable();
+ var firstBuild = false;
+ if (container == null) {
+ // Indirect to avoid deleting the style element.
+ container = new DivElement();
+
+ firstBuild = true;
+ }
+ children = [container];
+ container.children.clear();
+ container.children.add(table);
+ _makeCssClassUncopyable(table, "noCopy");
+ if (firstBuild) {
+ _scrollToCurrentPos();
+ }
+ }
+ }
+
+ Future _refresh() async {
+ _loadedScript = await _scripts.get(_isolate, _script.id);
+ await _refreshSourceReport();
+ await _computeAnnotations();
+ _r.dirty();
+ }
+
+ ButtonElement _refreshButton;
+ ButtonElement _toggleProfileButton;
+
+ int _currentLine;
+ int _currentCol;
+ int _startLine;
+ int _endLine;
+
+ Map<int, List<S.ServiceMap>> _rangeMap = {};
+ Set _callSites = new Set<S.CallSite>();
+ Set _possibleBreakpointLines = new Set<int>();
+ Map<int, ScriptLineProfile> _profileMap = {};
+
+ var _annotations = [];
+ var _annotationsCursor;
+
+ bool _includeProfile = false;
+
+ String makeLineClass(int line) {
+ return 'script-inset-line-$line';
+ }
+
+ void _scrollToCurrentPos() {
+ var lines = getElementsByClassName(makeLineClass(_currentLine));
+ if (lines.length > 0) {
+ lines[0].scrollIntoView();
+ }
+ }
+
+ Element a(String text) => new AnchorElement()..text = text;
+ Element span(String text) => new SpanElement()..text = text;
+
+ Element hitsCurrent(Element element) {
+ element.classes.add('hitsCurrent');
+ element.title = "";
+ return element;
+ }
+ Element hitsUnknown(Element element) {
+ element.classes.add('hitsNone');
+ element.title = "";
+ return element;
+ }
+ Element hitsNotExecuted(Element element) {
+ element.classes.add('hitsNotExecuted');
+ element.title = "Line did not execute";
+ return element;
+ }
+ Element hitsExecuted(Element element) {
+ element.classes.add('hitsExecuted');
+ element.title = "Line did execute";
+ return element;
+ }
+ Element hitsCompiled(Element element) {
+ element.classes.add('hitsCompiled');
+ element.title = "Line in compiled function";
+ return element;
+ }
+ Element hitsNotCompiled(Element element) {
+ element.classes.add('hitsNotCompiled');
+ element.title = "Line in uncompiled function";
+ return element;
+ }
+
+ Element container;
+
+ // Build _rangeMap and _callSites from a source report.
+ Future _refreshSourceReport() async {
+ var reports = [S.Isolate.kCallSitesReport,
+ S.Isolate.kPossibleBreakpointsReport];
+ if (_includeProfile) {
+ reports.add(S.Isolate.kProfileReport);
+ }
+ S.Isolate isolate = _isolate as S.Isolate;
+ var sourceReport = await isolate.getSourceReport(
+ reports,
+ script, _startPos, _endPos);
+ _possibleBreakpointLines = S.getPossibleBreakpointLines(sourceReport,
+ script);
+ _rangeMap.clear();
+ _callSites.clear();
+ _profileMap.clear();
+ for (var range in sourceReport['ranges']) {
+ int startLine = _loadedScript.tokenToLine(range['startPos']);
+ int endLine = _loadedScript.tokenToLine(range['endPos']);
+ // TODO(turnidge): Track down the root cause of null startLine/endLine.
+ if ((startLine != null) && (endLine != null)) {
+ for (var line = startLine; line <= endLine; line++) {
+ var rangeList = _rangeMap[line];
+ if (rangeList == null) {
+ _rangeMap[line] = [range];
+ } else {
+ rangeList.add(range);
+ }
+ }
+ }
+ if (_includeProfile && range['profile'] != null) {
+ List positions = range['profile']['positions'];
+ List exclusiveTicks = range['profile']['exclusiveTicks'];
+ List inclusiveTicks = range['profile']['inclusiveTicks'];
+ int sampleCount = range['profile']['metadata']['sampleCount'];
+ assert(positions.length == exclusiveTicks.length);
+ assert(positions.length == inclusiveTicks.length);
+ for (int i = 0; i < positions.length; i++) {
+ if (positions[i] is String) {
+ // String positions are classifying token positions.
+ // TODO(johnmccutchan): Add classifier data to UI.
+ continue;
+ }
+ int line = _loadedScript.tokenToLine(positions[i]);
+ ScriptLineProfile lineProfile = _profileMap[line];
+ if (lineProfile == null) {
+ lineProfile = new ScriptLineProfile(line, sampleCount);
+ _profileMap[line] = lineProfile;
+ }
+ lineProfile.process(exclusiveTicks[i], inclusiveTicks[i]);
+ }
+ }
+ if (range['compiled']) {
+ var rangeCallSites = range['callSites'];
+ if (rangeCallSites != null) {
+ for (var callSiteMap in rangeCallSites) {
+ _callSites.add(new S.CallSite.fromMap(callSiteMap, script));
+ }
+ }
+ }
+ }
+ }
+
+ Future _computeAnnotations() async {
+ _startLine = (_startPos != null
+ ? _loadedScript.tokenToLine(_startPos)
+ : 1 + _loadedScript.lineOffset);
+ _currentLine = (_currentPos != null
+ ? _loadedScript.tokenToLine(_currentPos)
+ : null);
+ _currentCol = (_currentPos != null
+ ? (_loadedScript.tokenToCol(_currentPos))
+ : null);
+ if (_currentCol != null) {
+ _currentCol--; // make this 0-based.
+ }
+
+ S.Script script = _loadedScript as S.Script;
+
+ _endLine = (_endPos != null
+ ? _loadedScript.tokenToLine(_endPos)
+ : script.lines.length + _loadedScript.lineOffset);
+
+ if (_startLine == null || _endLine == null) {
+ return;
+ }
+
+ _annotations.clear();
+
+ addCurrentExecutionAnnotation();
+ addBreakpointAnnotations();
+
+ if (!_inDebuggerContext && script.library != null) {
+ await loadDeclarationsOfLibrary(script.library);
+ addLibraryAnnotations();
+ addDependencyAnnotations();
+ addPartAnnotations();
+ addClassAnnotations();
+ addFieldAnnotations();
+ addFunctionAnnotations();
+ addCallSiteAnnotations();
+ }
+
+ addLocalVariableAnnotations();
+
+ _annotations.sort();
+ }
+
+ void addCurrentExecutionAnnotation() {
+ if (_currentLine != null) {
+ var a = new CurrentExecutionAnnotation(_isolate, _instances, _r.queue);
+ a.line = _currentLine;
+ a.columnStart = _currentCol;
+ S.Script script = _loadedScript as S.Script;
+ var length = script.guessTokenLength(_currentLine, _currentCol);
+ if (length == null) {
+ length = 1;
+ }
+ a.columnStop = _currentCol + length;
+ _annotations.add(a);
+ }
+ }
+
+ void addBreakpointAnnotations() {
+ S.Script script = _loadedScript as S.Script;
+ for (var line = _startLine; line <= _endLine; line++) {
+ var bpts = script.getLine(line).breakpoints;
+ if (bpts != null) {
+ for (var bpt in bpts) {
+ if (bpt.location != null) {
+ _annotations.add(new BreakpointAnnotation(_isolate, _instances,
+ _r.queue, bpt));
+ }
+ }
+ }
+ }
+ }
+
+ Future loadDeclarationsOfLibrary(S.Library lib) {
+ return lib.load().then((lib) {
+ var loads = [];
+ for (var func in lib.functions) {
+ loads.add(func.load());
+ }
+ for (var field in lib.variables) {
+ loads.add(field.load());
+ }
+ for (var cls in lib.classes) {
+ loads.add(loadDeclarationsOfClass(cls));
+ }
+ return Future.wait(loads);
+ });
+ }
+
+ Future loadDeclarationsOfClass(S.Class cls) {
+ return cls.load().then((cls) {
+ var loads = [];
+ for (var func in cls.functions) {
+ loads.add(func.load());
+ }
+ for (var field in cls.fields) {
+ loads.add(field.load());
+ }
+ return Future.wait(loads);
+ });
+ }
+
+ void addLibraryAnnotations() {
+ S.Script script = _loadedScript as S.Script;
+ for (S.ScriptLine line in script.lines) {
+ // TODO(rmacnak): Use a real scanner.
+ var pattern = new RegExp("library ${script.library.name}");
+ var match = pattern.firstMatch(line.text);
+ if (match != null) {
+ var anno = new LibraryAnnotation(_isolate, _instances, _r.queue,
+ _loadedScript.library,
+ Uris.inspect(isolate, object: _loadedScript.library));
+ anno.line = line.line;
+ anno.columnStart = match.start + 8;
+ anno.columnStop = match.end;
+ _annotations.add(anno);
+ }
+ // TODO(rmacnak): Use a real scanner.
+ pattern = new RegExp("part of ${script.library.name}");
+ match = pattern.firstMatch(line.text);
+ if (match != null) {
+ var anno = new LibraryAnnotation(_isolate, _instances, _r.queue,
+ _loadedScript.library,
+ Uris.inspect(isolate, object: _loadedScript.library));
+ anno.line = line.line;
+ anno.columnStart = match.start + 8;
+ anno.columnStop = match.end;
+ _annotations.add(anno);
+ }
+ }
+ }
+
+ M.Library resolveDependency(String relativeUri) {
+ S.Script script = _loadedScript as S.Script;
+ // This isn't really correct: we need to ask the embedder to do the
+ // uri canonicalization for us, but Observatory isn't in a position
+ // to invoke the library tag handler. Handle the most common cases.
+ var targetUri = Uri.parse(_loadedScript.library.uri).resolve(relativeUri);
+ for (M.Library l in script.isolate.libraries) {
+ if (targetUri.toString() == l.uri) {
+ return l;
+ }
+ }
+ if (targetUri.scheme == 'package') {
+ targetUri = "packages/${targetUri.path}";
+ for (M.Library l in script.isolate.libraries) {
+ if (targetUri.toString() == l.uri) {
+ return l;
+ }
+ }
+ }
+
+ print("Could not resolve library dependency: $relativeUri");
+ return null;
+ }
+
+ void addDependencyAnnotations() {
+ S.Script script = _loadedScript as S.Script;
+ // TODO(rmacnak): Use a real scanner.
+ var patterns = [
+ new RegExp("import '(.*)'"),
+ new RegExp('import "(.*)"'),
+ new RegExp("export '(.*)'"),
+ new RegExp('export "(.*)"'),
+ ];
+ for (S.ScriptLine line in script.lines) {
+ for (var pattern in patterns) {
+ var match = pattern.firstMatch(line.text);
+ if (match != null) {
+ M.Library target = resolveDependency(match[1]);
+ if (target != null) {
+ var anno = new LibraryAnnotation(_isolate, _instances, _r.queue,
+ target, Uris.inspect(isolate, object: target));
+ anno.line = line.line;
+ anno.columnStart = match.start + 8;
+ anno.columnStop = match.end - 1;
+ _annotations.add(anno);
+ }
+ }
+ }
+ }
+ }
+
+ M.Script resolvePart(String relativeUri) {
+ S.Script script = _loadedScript as S.Script;
+ var rootUri = Uri.parse(script.library.uri);
+ if (rootUri.scheme == 'dart') {
+ // The relative paths from dart:* libraries to their parts are not valid.
+ rootUri = new Uri.directory(script.library.uri);
+ }
+ var targetUri = rootUri.resolve(relativeUri);
+ for (M.Script s in script.library.scripts) {
+ if (targetUri.toString() == s.uri) {
+ return s;
+ }
+ }
+ print("Could not resolve part: $relativeUri");
+ return null;
+ }
+
+ void addPartAnnotations() {
+ S.Script script = _loadedScript as S.Script;
+ // TODO(rmacnak): Use a real scanner.
+ var patterns = [
+ new RegExp("part '(.*)'"),
+ new RegExp('part "(.*)"'),
+ ];
+ for (S.ScriptLine line in script.lines) {
+ for (var pattern in patterns) {
+ var match = pattern.firstMatch(line.text);
+ if (match != null) {
+ S.Script part = resolvePart(match[1]);
+ if (part != null) {
+ var anno = new PartAnnotation(_isolate, _instances, _r.queue, part,
+ Uris.inspect(isolate, object: part));
+ anno.line = line.line;
+ anno.columnStart = match.start + 6;
+ anno.columnStop = match.end - 1;
+ _annotations.add(anno);
+ }
+ }
+ }
+ }
+ }
+
+ void addClassAnnotations() {
+ S.Script script = _loadedScript as S.Script;
+ for (var cls in script.library.classes) {
+ if ((cls.location != null) && (cls.location.script == script)) {
+ var a = new ClassDeclarationAnnotation(_isolate, _instances, _r.queue,
+ cls, Uris.inspect(isolate, object: cls));
+ _annotations.add(a);
+ }
+ }
+ }
+
+ void addFieldAnnotations() {
+ S.Script script = _loadedScript as S.Script;
+ for (var field in script.library.variables) {
+ if ((field.location != null) && (field.location.script == script)) {
+ var a = new FieldDeclarationAnnotation(_isolate, _instances, _r.queue,
+ field, Uris.inspect(isolate, object: field));
+ _annotations.add(a);
+ }
+ }
+ for (var cls in script.library.classes) {
+ for (var field in cls.fields) {
+ if ((field.location != null) && (field.location.script == script)) {
+ var a = new FieldDeclarationAnnotation(_isolate, _instances, _r.queue,
+ field, Uris.inspect(isolate, object: field));
+ _annotations.add(a);
+ }
+ }
+ }
+ }
+
+ void addFunctionAnnotations() {
+ S.Script script = _loadedScript as S.Script;
+ for (var func in script.library.functions) {
+ if ((func.location != null) &&
+ (func.location.script == script) &&
+ (func.kind != M.FunctionKind.implicitGetter) &&
+ (func.kind != M.FunctionKind.implicitSetter)) {
+ // We annotate a field declaration with the field instead of the
+ // implicit getter or setter.
+ var a = new FunctionDeclarationAnnotation(_isolate, _instances,
+ _r.queue, func, Uris.inspect(isolate, object: func));
+ _annotations.add(a);
+ }
+ }
+ for (var cls in script.library.classes) {
+ S.Script script = _loadedScript as S.Script;
+ for (var func in cls.functions) {
+ if ((func.location != null) &&
+ (func.location.script == script) &&
+ (func.kind != M.FunctionKind.implicitGetter) &&
+ (func.kind != M.FunctionKind.implicitSetter)) {
+ // We annotate a field declaration with the field instead of the
+ // implicit getter or setter.
+ var a = new FunctionDeclarationAnnotation(_isolate, _instances,
+ _r.queue, func, Uris.inspect(isolate, object: func));
+ _annotations.add(a);
+ }
+ }
+ }
+ }
+
+ void addCallSiteAnnotations() {
+ for (var callSite in _callSites) {
+ _annotations.add(new CallSiteAnnotation(_isolate, _instances, _r.queue,
+ callSite));
+ }
+ }
+
+ void addLocalVariableAnnotations() {
+ S.Script script = _loadedScript as S.Script;
+ // We have local variable information.
+ if (_variables != null) {
+ // For each variable.
+ for (var variable in _variables) {
+ // Find variable usage locations.
+ var locations = script.scanForLocalVariableLocations(
+ variable['name'],
+ variable['_tokenPos'],
+ variable['_endTokenPos']);
+
+ // Annotate locations.
+ for (var location in locations) {
+ _annotations.add(new LocalVariableAnnotation(_isolate, _instances,
+ _r.queue, location,
+ variable['value']));
+ }
+ }
+ }
+ }
+
+ ButtonElement _newRefreshButton() {
+ var button = new ButtonElement();
+ button.classes = const ['refresh'];
+ button.onClick.listen((_) async {
+ button.disabled = true;
+ await _refresh();
+ button.disabled = false;
+ });
+ button.title = 'Refresh coverage';
+ button.text = '↺';
+ return button;
+ }
+
+ ButtonElement _newToggleProfileButton() {
+ ButtonElement button = new ButtonElement();
+ button.classes = _includeProfile ? const ['toggle-profile', 'enabled']
+ : const ['toggle-profile'];
+ button.title = 'Toggle CPU profile information';
+ button.onClick.listen((_) async {
+ _includeProfile = !_includeProfile;
+ button.classes.toggle('enabled');
+ button.disabled = true;
+ _refresh();
+ button.disabled = false;
+ });
+ button.text = '🔥';
+ return button;
+ }
+
+ Element linesTable() {
+ S.Script script = _loadedScript as S.Script;
+ var table = new DivElement();
+ table.classes.add("sourceTable");
+
+ _refreshButton = _newRefreshButton();
+ _toggleProfileButton = _newToggleProfileButton();
+ table.append(_refreshButton);
+ table.append(_toggleProfileButton);
+
+ if (_startLine == null || _endLine == null) {
+ return table;
+ }
+
+ var endLine = (_endPos != null
+ ? _loadedScript.tokenToLine(_endPos)
+ : script.lines.length + _loadedScript.lineOffset);
+ var lineNumPad = endLine.toString().length;
+
+ _annotationsCursor = 0;
+
+ int blankLineCount = 0;
+ for (int i = _startLine; i <= _endLine; i++) {
+ var line = script.getLine(i);
+ if (line.isBlank) {
+ // Try to introduce elipses if there are 4 or more contiguous
+ // blank lines.
+ blankLineCount++;
+ } else {
+ if (blankLineCount > 0) {
+ int firstBlank = i - blankLineCount;
+ int lastBlank = i - 1;
+ if (blankLineCount < 4) {
+ // Too few blank lines for an elipsis.
+ for (int j = firstBlank; j <= lastBlank; j++) {
+ table.append(lineElement(script.getLine(j), lineNumPad));
+ }
+ } else {
+ // Add an elipsis for the skipped region.
+ table.append(lineElement(script.getLine(firstBlank), lineNumPad));
+ table.append(lineElement(null, lineNumPad));
+ table.append(lineElement(script.getLine(lastBlank), lineNumPad));
+ }
+ blankLineCount = 0;
+ }
+ table.append(lineElement(line, lineNumPad));
+ }
+ }
+
+ return table;
+ }
+
+ // Assumes annotations are sorted.
+ Annotation nextAnnotationOnLine(int line) {
+ if (_annotationsCursor >= _annotations.length) return null;
+ var annotation = _annotations[_annotationsCursor];
+
+ // Fast-forward past any annotations before the first line that
+ // we are displaying.
+ while (annotation.line < line) {
+ _annotationsCursor++;
+ if (_annotationsCursor >= _annotations.length) return null;
+ annotation = _annotations[_annotationsCursor];
+ }
+
+ // Next annotation is for a later line, don't advance past it.
+ if (annotation.line != line) return null;
+ _annotationsCursor++;
+ return annotation;
+ }
+
+ Element lineElement(S.ScriptLine line, int lineNumPad) {
+ var e = new DivElement();
+ e.classes.add("sourceRow");
+ e.append(lineBreakpointElement(line));
+ e.append(lineNumberElement(line, lineNumPad));
+ if (_includeProfile) {
+ e.append(lineProfileElement(line, false));
+ e.append(lineProfileElement(line, true));
+ }
+ e.append(lineSourceElement(line));
+ return e;
+ }
+
+ Element lineProfileElement(S.ScriptLine line, bool self) {
+ var e = span('');
+ e.classes.add('noCopy');
+ if (self) {
+ e.title = 'Self %';
+ } else {
+ e.title = 'Total %';
+ }
+
+ if (line == null) {
+ e.classes.add('notSourceProfile');
+ e.text = nbsp;
+ return e;
+ }
+
+ var ranges = _rangeMap[line.line];
+ if ((ranges == null) || ranges.isEmpty) {
+ e.classes.add('notSourceProfile');
+ e.text = nbsp;
+ return e;
+ }
+
+ ScriptLineProfile lineProfile = _profileMap[line.line];
+ if (lineProfile == null) {
+ e.classes.add('noProfile');
+ e.text = nbsp;
+ return e;
+ }
+
+ if (self) {
+ e.text = lineProfile.formattedSelfTicks;
+ } else {
+ e.text = lineProfile.formattedTotalTicks;
+ }
+
+ if (lineProfile.isHot(self)) {
+ e.classes.add('hotProfile');
+ } else if (lineProfile.isMedium(self)) {
+ e.classes.add('mediumProfile');
+ } else {
+ e.classes.add('coldProfile');
+ }
+
+ return e;
+ }
+
+ Element lineBreakpointElement(S.ScriptLine line) {
+ var e = new DivElement();
+ if (line == null || !_possibleBreakpointLines.contains(line.line)) {
+ e.classes.add('noCopy');
+ e.classes.add("emptyBreakpoint");
+ e.text = nbsp;
+ return e;
+ }
+
+ e.text = 'B';
+ var busy = false;
+ void update() {
+ e.classes.clear();
+ e.classes.add('noCopy');
+ if (busy) {
+ e.classes.add("busyBreakpoint");
+ } else if (line.breakpoints != null) {
+ bool resolved = false;
+ for (var bpt in line.breakpoints) {
+ if (bpt.resolved) {
+ resolved = true;
+ break;
+ }
+ }
+ if (resolved) {
+ e.classes.add("resolvedBreakpoint");
+ } else {
+ e.classes.add("unresolvedBreakpoint");
+ }
+ } else {
+ e.classes.add("possibleBreakpoint");
+ }
+ }
+
+ line.changes.listen((_) => update());
+ e.onClick.listen((event) {
+ if (busy) {
+ return;
+ }
+ busy = true;
+ if (line.breakpoints == null) {
+ // No breakpoint. Add it.
+ line.script.isolate.addBreakpoint(line.script, line.line)
+ .catchError((e, st) {
+ if (e is! S.ServerRpcException ||
+ (e as S.ServerRpcException).code !=
+ S.ServerRpcException.kCannotAddBreakpoint) {
+ ObservatoryApplication.app.handleException(e, st);
+ }})
+ .whenComplete(() {
+ busy = false;
+ update();
+ });
+ } else {
+ // Existing breakpoint. Remove it.
+ List pending = [];
+ for (var bpt in line.breakpoints) {
+ pending.add(line.script.isolate.removeBreakpoint(bpt));
+ }
+ Future.wait(pending).then((_) {
+ busy = false;
+ update();
+ });
+ }
+ update();
+ });
+ update();
+ return e;
+ }
+
+ Element lineNumberElement(S.ScriptLine line, int lineNumPad) {
+ var lineNumber = line == null ? "..." : line.line;
+ var e = span("$nbsp${lineNumber.toString().padLeft(lineNumPad,nbsp)}$nbsp");
+ e.classes.add('noCopy');
+ if (lineNumber == _currentLine) {
+ hitsCurrent(e);
+ return e;
+ }
+ var ranges = _rangeMap[lineNumber];
+ if ((ranges == null) || ranges.isEmpty) {
+ // This line is not code.
+ hitsUnknown(e);
+ return e;
+ }
+ bool compiled = true;
+ bool hasCallInfo = false;
+ bool executed = false;
+ for (var range in ranges) {
+ if (range['compiled']) {
+ for (var callSite in range['callSites']) {
+ var callLine = line.script.tokenToLine(callSite['tokenPos']);
+ if (lineNumber == callLine) {
+ // The call site is on the current line.
+ hasCallInfo = true;
+ for (var cacheEntry in callSite['cacheEntries']) {
+ if (cacheEntry['count'] > 0) {
+ // If any call site on the line has been executed, we
+ // mark the line as executed.
+ executed = true;
+ break;
+ }
+ }
+ }
+ }
+ } else {
+ // If any range isn't compiled, show the line as not compiled.
+ // This is necessary so that nested functions appear to be uncompiled.
+ compiled = false;
+ }
+ }
+ if (executed) {
+ hitsExecuted(e);
+ } else if (hasCallInfo) {
+ hitsNotExecuted(e);
+ } else if (compiled) {
+ hitsCompiled(e);
+ } else {
+ hitsNotCompiled(e);
+ }
+ return e;
+ }
+
+ Element lineSourceElement(S.ScriptLine line) {
+ var e = new DivElement();
+ e.classes.add("sourceItem");
+
+ if (line != null) {
+ e.classes.add(makeLineClass(line.line));
+ if (line.line == _currentLine) {
+ e.classes.add("currentLine");
+ }
+
+ var position = 0;
+ consumeUntil(var stop) {
+ if (stop <= position) {
+ return null; // Empty gap between annotations/boundries.
+ }
+ if (stop > line.text.length) {
+ // Approximated token length can run past the end of the line.
+ stop = line.text.length;
+ }
+
+ var chunk = line.text.substring(position, stop);
+ var chunkNode = span(chunk);
+ e.append(chunkNode);
+ position = stop;
+ return chunkNode;
+ }
+
+ // TODO(rmacnak): Tolerate overlapping annotations.
+ var annotation;
+ while ((annotation = nextAnnotationOnLine(line.line)) != null) {
+ consumeUntil(annotation.columnStart);
+ annotation.applyStyleTo(consumeUntil(annotation.columnStop));
+ }
+ consumeUntil(line.text.length);
+ }
+
+ // So blank lines are included when copying script to the clipboard.
+ e.append(span('\n'));
+
+ return e;
+ }
+
+ /// Exclude nodes from being copied, for example the line numbers and
+ /// breakpoint toggles in script insets. Must be called after [root]'s
+ /// children have been added, and only supports one node at a time.
+ static void _makeCssClassUncopyable(Element root, String className) {
+ var noCopyNodes = root.getElementsByClassName(className);
+ for (var node in noCopyNodes) {
+ node.style.setProperty('-moz-user-select', 'none');
+ node.style.setProperty('-khtml-user-select', 'none');
+ node.style.setProperty('-webkit-user-select', 'none');
+ node.style.setProperty('-ms-user-select', 'none');
+ node.style.setProperty('user-select', 'none');
+ }
+ root.onCopy.listen((event) {
+ // Mark the nodes as hidden before the copy happens, then mark them as
+ // visible on the next event loop turn.
+ for (var node in noCopyNodes) {
+ node.style.visibility = 'hidden';
+ }
+ Timer.run(() {
+ for (var node in noCopyNodes) {
+ node.style.visibility = 'visible';
+ }
+ });
+ });
+ }
+}
const nbsp = "\u00A0";
@@ -56,11 +973,16 @@
abstract class Annotation implements Comparable<Annotation> {
+ M.IsolateRef _isolate;
+ M.InstanceRepository _instances;
+ RenderingQueue queue;
int line;
int columnStart;
int columnStop;
int get priority;
+ Annotation(this._isolate, this._instances, this.queue);
+
void applyStyleTo(element);
int compareTo(Annotation other) {
@@ -99,15 +1021,18 @@
}
Element serviceRef(object) {
- AnyServiceRefElement e = new Element.tag("any-service-ref");
- e.ref = object;
- return e;
+ return anyRef(_isolate, object, _instances, queue: queue);
}
}
class CurrentExecutionAnnotation extends Annotation {
int priority = 0; // highest priority.
+ CurrentExecutionAnnotation(M.IsolateRef isolate,
+ M.InstanceRepository instances,
+ RenderingQueue queue)
+ : super(isolate, instances, queue);
+
void applyStyleTo(element) {
if (element == null) {
return; // TODO(rmacnak): Handling overlapping annotations.
@@ -118,17 +1043,19 @@
}
class BreakpointAnnotation extends Annotation {
- Breakpoint bpt;
+ M.Breakpoint bpt;
int priority = 1;
- BreakpointAnnotation(this.bpt) {
+ BreakpointAnnotation(M.IsolateRef isolate, M.InstanceRepository instances,
+ RenderingQueue queue, this.bpt)
+ : super(isolate, instances, queue) {
var script = bpt.location.script;
var location = bpt.location;
if (location.tokenPos != null) {
var pos = location.tokenPos;
line = script.tokenToLine(pos);
columnStart = script.tokenToCol(pos) - 1; // tokenToCol is 1-origin.
- } else if (location is UnresolvedSourceLocation) {
+ } else if (location is M.UnresolvedSourceLocation) {
line = location.line;
columnStart = location.column;
if (columnStart == null) {
@@ -160,11 +1087,13 @@
}
class LibraryAnnotation extends Annotation {
- Library target;
+ S.Library target;
String url;
int priority = 2;
- LibraryAnnotation(this.target, this.url);
+ LibraryAnnotation(M.IsolateRef isolate, M.InstanceRepository instances,
+ RenderingQueue queue, this.target, this.url)
+ : super(isolate, instances, queue);
void applyStyleTo(element) {
if (element == null) {
@@ -176,11 +1105,13 @@
}
class PartAnnotation extends Annotation {
- Script part;
+ S.Script part;
String url;
int priority = 2;
- PartAnnotation(this.part, this.url);
+ PartAnnotation(M.IsolateRef isolate, M.InstanceRepository instances,
+ RenderingQueue queue, this.part, this.url)
+ : super(isolate, instances, queue);
void applyStyleTo(element) {
if (element == null) {
@@ -195,7 +1126,9 @@
final value;
int priority = 2;
- LocalVariableAnnotation(LocalVarLocation location, this.value) {
+ LocalVariableAnnotation(M.IsolateRef isolate, M.InstanceRepository instances,
+ RenderingQueue queue, S.LocalVarLocation location,
+ this.value): super(isolate, instances, queue) {
line = location.line;
columnStart = location.column;
columnStop = location.endColumn;
@@ -211,10 +1144,12 @@
}
class CallSiteAnnotation extends Annotation {
- CallSite callSite;
+ S.CallSite callSite;
int priority = 2;
- CallSiteAnnotation(this.callSite) {
+ CallSiteAnnotation(M.IsolateRef isolate, M.InstanceRepository instances,
+ RenderingQueue queue, this.callSite)
+ : super(isolate, instances, queue) {
line = callSite.line;
columnStart = callSite.column - 1; // Call site is 1-origin.
var tokenLength = callSite.script.guessTokenLength(line, columnStart);
@@ -261,9 +1196,11 @@
String url;
int priority = 2;
- DeclarationAnnotation(decl, this.url) {
+ DeclarationAnnotation(M.IsolateRef isolate, M.InstanceRepository instances,
+ RenderingQueue queue, decl, this.url)
+ : super(isolate, instances, queue) {
assert(decl.loaded);
- SourceLocation location = decl.location;
+ S.SourceLocation location = decl.location;
if (location == null) {
line = 0;
columnStart = 0;
@@ -271,7 +1208,7 @@
return;
}
- Script script = location.script;
+ S.Script script = location.script;
line = script.tokenToLine(location.tokenPos);
columnStart = script.tokenToCol(location.tokenPos);
if ((line == null) || (columnStart == null)) {
@@ -296,11 +1233,13 @@
}
class ClassDeclarationAnnotation extends DeclarationAnnotation {
- Class klass;
+ S.Class klass;
- ClassDeclarationAnnotation(Class cls, String url)
+ ClassDeclarationAnnotation(M.IsolateRef isolate,
+ M.InstanceRepository instances,
+ RenderingQueue queue, S.Class cls, String url)
: klass = cls,
- super(cls, url);
+ super(isolate, instances, queue, cls, url);
void applyStyleTo(element) {
if (element == null) {
@@ -312,11 +1251,13 @@
}
class FieldDeclarationAnnotation extends DeclarationAnnotation {
- Field field;
+ S.Field field;
- FieldDeclarationAnnotation(Field fld, String url)
+ FieldDeclarationAnnotation(M.IsolateRef isolate,
+ M.InstanceRepository instances,
+ RenderingQueue queue, S.Field fld, String url)
: field = fld,
- super(fld, url);
+ super(isolate, instances, queue, fld, url);
void applyStyleTo(element) {
if (element == null) {
@@ -329,11 +1270,14 @@
}
class FunctionDeclarationAnnotation extends DeclarationAnnotation {
- ServiceFunction function;
+ S.ServiceFunction function;
- FunctionDeclarationAnnotation(ServiceFunction func, String url)
+ FunctionDeclarationAnnotation(M.IsolateRef isolate,
+ M.InstanceRepository instances,
+ RenderingQueue queue, S.ServiceFunction func,
+ String url)
: function = func,
- super(func, url);
+ super(isolate, instances, queue, func, url);
void applyStyleTo(element) {
if (element == null) {
@@ -400,980 +1344,3 @@
bool isHot(bool self) => _percent(self) > kHotThreshold;
bool isMedium(bool self) => _percent(self) > kMediumThreshold;
}
-
-/// Box with script source code in it.
-@CustomTag('script-inset')
-class ScriptInsetElement extends ObservatoryElement {
- @published Script script;
- @published int startPos;
- @published int endPos;
-
- /// Set the height to make the script inset scroll. Otherwise it
- /// will show from startPos to endPos.
- @published String height = null;
-
- @published int currentPos;
- @published bool inDebuggerContext = false;
- @published ObservableList variables;
-
- @published Element scroller;
- RefreshButtonElement _refreshButton;
- ToggleButtonElement _toggleProfileButton;
-
- int _currentLine;
- int _currentCol;
- int _startLine;
- int _endLine;
-
- Map<int, List<ServiceMap>> _rangeMap = {};
- Set _callSites = new Set<CallSite>();
- Set _possibleBreakpointLines = new Set<int>();
- Map<int, ScriptLineProfile> _profileMap = {};
-
- var annotations = [];
- var annotationsCursor;
-
- StreamSubscription _scriptChangeSubscription;
- Future<StreamSubscription> _debugSubscriptionFuture;
- StreamSubscription _scrollSubscription;
-
- bool hasLoadedLibraryDeclarations = false;
- bool _includeProfile = false;
-
- String makeLineId(int line) {
- return 'line-$line';
- }
-
- void _scrollToCurrentPos() {
- var line = shadowRoot.getElementById(makeLineId(_currentLine));
- if (line != null) {
- line.scrollIntoView();
- }
- }
-
- void attached() {
- super.attached();
- _debugSubscriptionFuture =
- app.vm.listenEventStream(VM.kDebugStream, _onDebugEvent);
- if (scroller != null) {
- _scrollSubscription = scroller.onScroll.listen(_onScroll);
- } else {
- _scrollSubscription = window.onScroll.listen(_onScroll);
- }
- }
-
- void detached() {
- cancelFutureSubscription(_debugSubscriptionFuture);
- _debugSubscriptionFuture = null;
- if (_scrollSubscription != null) {
- _scrollSubscription.cancel();
- _scrollSubscription = null;
- }
- if (_scriptChangeSubscription != null) {
- // Don't leak. If only Dart and Javascript exposed weak references...
- _scriptChangeSubscription.cancel();
- _scriptChangeSubscription = null;
- }
- super.detached();
- }
-
- void _onScroll(event) {
- if (_refreshButton != null) {
- var newTop = _buttonTop(_refreshButton);
- if (_refreshButton.style.top != newTop) {
- _refreshButton.style.top = '${newTop}px';
- }
- }
- if (_toggleProfileButton != null) {
- var newTop = _buttonTop(_toggleProfileButton);
- if (_toggleProfileButton.style.top != newTop) {
- _toggleProfileButton.style.top = '${newTop}px';
- }
- }
- }
-
- void _onDebugEvent(event) {
- if (script == null) {
- return;
- }
- switch (event.kind) {
- case ServiceEvent.kBreakpointAdded:
- case ServiceEvent.kBreakpointResolved:
- case ServiceEvent.kBreakpointRemoved:
- var loc = event.breakpoint.location;
- if (loc.script == script) {
- int line;
- if (loc.tokenPos != null) {
- line = script.tokenToLine(loc.tokenPos);
- } else {
- line = loc.line;
- }
- if ((line >= _startLine) && (line <= _endLine)) {
- _updateTask.queue();
- }
- }
- break;
- default:
- // Ignore.
- break;
- }
- }
-
- void currentPosChanged(oldValue) {
- _updateTask.queue();
- _scrollToCurrentPos();
- }
-
- void startPosChanged(oldValue) {
- _updateTask.queue();
- }
-
- void endPosChanged(oldValue) {
- _updateTask.queue();
- }
-
- void scriptChanged(oldValue) {
- _updateTask.queue();
- }
-
- void variablesChanged(oldValue) {
- _updateTask.queue();
- }
-
- Element a(String text) => new AnchorElement()..text = text;
- Element span(String text) => new SpanElement()..text = text;
-
- Element hitsCurrent(Element element) {
- element.classes.add('hitsCurrent');
- element.title = "";
- return element;
- }
- Element hitsUnknown(Element element) {
- element.classes.add('hitsNone');
- element.title = "";
- return element;
- }
- Element hitsNotExecuted(Element element) {
- element.classes.add('hitsNotExecuted');
- element.title = "Line did not execute";
- return element;
- }
- Element hitsExecuted(Element element) {
- element.classes.add('hitsExecuted');
- element.title = "Line did execute";
- return element;
- }
- Element hitsCompiled(Element element) {
- element.classes.add('hitsCompiled');
- element.title = "Line in compiled function";
- return element;
- }
- Element hitsNotCompiled(Element element) {
- element.classes.add('hitsNotCompiled');
- element.title = "Line in uncompiled function";
- return element;
- }
-
- Element container;
-
- Future _refresh() async {
- await update();
- }
-
- // Build _rangeMap and _callSites from a source report.
- Future _refreshSourceReport() async {
- var reports = [Isolate.kCallSitesReport,
- Isolate.kPossibleBreakpointsReport];
- if (_includeProfile) {
- reports.add(Isolate.kProfileReport);
- }
- var sourceReport = await script.isolate.getSourceReport(
- reports,
- script, startPos, endPos);
- _possibleBreakpointLines = getPossibleBreakpointLines(sourceReport, script);
- _rangeMap.clear();
- _callSites.clear();
- _profileMap.clear();
- for (var range in sourceReport['ranges']) {
- int startLine = script.tokenToLine(range['startPos']);
- int endLine = script.tokenToLine(range['endPos']);
- // TODO(turnidge): Track down the root cause of null startLine/endLine.
- if ((startLine != null) && (endLine != null)) {
- for (var line = startLine; line <= endLine; line++) {
- var rangeList = _rangeMap[line];
- if (rangeList == null) {
- _rangeMap[line] = [range];
- } else {
- rangeList.add(range);
- }
- }
- }
- if (_includeProfile && range['profile'] != null) {
- List positions = range['profile']['positions'];
- List exclusiveTicks = range['profile']['exclusiveTicks'];
- List inclusiveTicks = range['profile']['inclusiveTicks'];
- int sampleCount = range['profile']['metadata']['sampleCount'];
- assert(positions.length == exclusiveTicks.length);
- assert(positions.length == inclusiveTicks.length);
- for (int i = 0; i < positions.length; i++) {
- if (positions[i] is String) {
- // String positions are classifying token positions.
- // TODO(johnmccutchan): Add classifier data to UI.
- continue;
- }
- int line = script.tokenToLine(positions[i]);
- ScriptLineProfile lineProfile = _profileMap[line];
- if (lineProfile == null) {
- lineProfile = new ScriptLineProfile(line, sampleCount);
- _profileMap[line] = lineProfile;
- }
- lineProfile.process(exclusiveTicks[i], inclusiveTicks[i]);
- }
- }
- if (range['compiled']) {
- var rangeCallSites = range['callSites'];
- if (rangeCallSites != null) {
- for (var callSiteMap in rangeCallSites) {
- _callSites.add(new CallSite.fromMap(callSiteMap, script));
- }
- }
- }
- }
- }
-
- Task _updateTask;
- Future update() async {
- assert(_updateTask != null);
- if (script == null) {
- // We may have previously had a script.
- if (container != null) {
- container.children.clear();
- }
- return;
- }
- if (!script.loaded) {
- await script.load();
- }
- if (_scriptChangeSubscription == null) {
- _scriptChangeSubscription = script.changes.listen((_) => update());
- }
- await _refreshSourceReport();
-
- computeAnnotations();
-
- var table = linesTable();
- var firstBuild = false;
- if (container == null) {
- // Indirect to avoid deleting the style element.
- container = new DivElement();
- shadowRoot.append(container);
- firstBuild = true;
- }
- container.children.clear();
- container.children.add(table);
- makeCssClassUncopyable(table, "noCopy");
- if (firstBuild) {
- _scrollToCurrentPos();
- }
- }
-
- void computeAnnotations() {
- _startLine = (startPos != null
- ? script.tokenToLine(startPos)
- : 1 + script.lineOffset);
- _currentLine = (currentPos != null
- ? script.tokenToLine(currentPos)
- : null);
- _currentCol = (currentPos != null
- ? (script.tokenToCol(currentPos))
- : null);
- if (_currentCol != null) {
- _currentCol--; // make this 0-based.
- }
-
- _endLine = (endPos != null
- ? script.tokenToLine(endPos)
- : script.lines.length + script.lineOffset);
-
- if (_startLine == null || _endLine == null) {
- return;
- }
-
- annotations.clear();
-
- addCurrentExecutionAnnotation();
- addBreakpointAnnotations();
-
- if (!inDebuggerContext && script.library != null) {
- if (hasLoadedLibraryDeclarations) {
- addLibraryAnnotations();
- addDependencyAnnotations();
- addPartAnnotations();
- addClassAnnotations();
- addFieldAnnotations();
- addFunctionAnnotations();
- addCallSiteAnnotations();
- } else {
- loadDeclarationsOfLibrary(script.library).then((_) {
- hasLoadedLibraryDeclarations = true;
- update();
- });
- }
- }
-
- addLocalVariableAnnotations();
-
- annotations.sort();
- }
-
- void addCurrentExecutionAnnotation() {
- if (_currentLine != null) {
- var a = new CurrentExecutionAnnotation();
- a.line = _currentLine;
- a.columnStart = _currentCol;
- var length = script.guessTokenLength(_currentLine, _currentCol);
- if (length == null) {
- length = 1;
- }
- a.columnStop = _currentCol + length;
- annotations.add(a);
- }
- }
-
- void addBreakpointAnnotations() {
- for (var line = _startLine; line <= _endLine; line++) {
- var bpts = script.getLine(line).breakpoints;
- if (bpts != null) {
- for (var bpt in bpts) {
- if (bpt.location != null) {
- annotations.add(new BreakpointAnnotation(bpt));
- }
- }
- }
- }
- }
-
- Future loadDeclarationsOfLibrary(Library lib) {
- return lib.load().then((lib) {
- var loads = [];
- for (var func in lib.functions) {
- loads.add(func.load());
- }
- for (var field in lib.variables) {
- loads.add(field.load());
- }
- for (var cls in lib.classes) {
- loads.add(loadDeclarationsOfClass(cls));
- }
- return Future.wait(loads);
- });
- }
-
- Future loadDeclarationsOfClass(Class cls) {
- return cls.load().then((cls) {
- var loads = [];
- for (var func in cls.functions) {
- loads.add(func.load());
- }
- for (var field in cls.fields) {
- loads.add(field.load());
- }
- return Future.wait(loads);
- });
- }
-
- String inspectLink(ServiceObject ref) {
- return gotoLink('/inspect', ref);
- }
-
- void addLibraryAnnotations() {
- for (ScriptLine line in script.lines) {
- // TODO(rmacnak): Use a real scanner.
- var pattern = new RegExp("library ${script.library.name}");
- var match = pattern.firstMatch(line.text);
- if (match != null) {
- var anno = new LibraryAnnotation(script.library,
- inspectLink(script.library));
- anno.line = line.line;
- anno.columnStart = match.start + 8;
- anno.columnStop = match.end;
- annotations.add(anno);
- }
- // TODO(rmacnak): Use a real scanner.
- pattern = new RegExp("part of ${script.library.name}");
- match = pattern.firstMatch(line.text);
- if (match != null) {
- var anno = new LibraryAnnotation(script.library,
- inspectLink(script.library));
- anno.line = line.line;
- anno.columnStart = match.start + 8;
- anno.columnStop = match.end;
- annotations.add(anno);
- }
- }
- }
-
- Library resolveDependency(String relativeUri) {
- // This isn't really correct: we need to ask the embedder to do the
- // uri canonicalization for us, but Observatory isn't in a position
- // to invoke the library tag handler. Handle the most common cases.
- var targetUri = Uri.parse(script.library.uri).resolve(relativeUri);
- for (Library l in script.isolate.libraries) {
- if (targetUri.toString() == l.uri) {
- return l;
- }
- }
- if (targetUri.scheme == 'package') {
- targetUri = "packages/${targetUri.path}";
- for (Library l in script.isolate.libraries) {
- if (targetUri.toString() == l.uri) {
- return l;
- }
- }
- }
-
- Logger.root.info("Could not resolve library dependency: $relativeUri");
- return null;
- }
-
- void addDependencyAnnotations() {
- // TODO(rmacnak): Use a real scanner.
- var patterns = [
- new RegExp("import '(.*)'"),
- new RegExp('import "(.*)"'),
- new RegExp("export '(.*)'"),
- new RegExp('export "(.*)"'),
- ];
- for (ScriptLine line in script.lines) {
- for (var pattern in patterns) {
- var match = pattern.firstMatch(line.text);
- if (match != null) {
- Library target = resolveDependency(match[1]);
- if (target != null) {
- var anno = new LibraryAnnotation(target, inspectLink(target));
- anno.line = line.line;
- anno.columnStart = match.start + 8;
- anno.columnStop = match.end - 1;
- annotations.add(anno);
- }
- }
- }
- }
- }
-
- Script resolvePart(String relativeUri) {
- var rootUri = Uri.parse(script.library.uri);
- if (rootUri.scheme == 'dart') {
- // The relative paths from dart:* libraries to their parts are not valid.
- rootUri = new Uri.directory(script.library.uri);
- }
- var targetUri = rootUri.resolve(relativeUri);
- for (Script s in script.library.scripts) {
- if (targetUri.toString() == s.uri) {
- return s;
- }
- }
- Logger.root.info("Could not resolve part: $relativeUri");
- return null;
- }
-
- void addPartAnnotations() {
- // TODO(rmacnak): Use a real scanner.
- var patterns = [
- new RegExp("part '(.*)'"),
- new RegExp('part "(.*)"'),
- ];
- for (ScriptLine line in script.lines) {
- for (var pattern in patterns) {
- var match = pattern.firstMatch(line.text);
- if (match != null) {
- Script part = resolvePart(match[1]);
- if (part != null) {
- var anno = new PartAnnotation(part, inspectLink(part));
- anno.line = line.line;
- anno.columnStart = match.start + 6;
- anno.columnStop = match.end - 1;
- annotations.add(anno);
- }
- }
- }
- }
- }
-
- void addClassAnnotations() {
- for (var cls in script.library.classes) {
- if ((cls.location != null) && (cls.location.script == script)) {
- var a = new ClassDeclarationAnnotation(cls, inspectLink(cls));
- annotations.add(a);
- }
- }
- }
-
- void addFieldAnnotations() {
- for (var field in script.library.variables) {
- if ((field.location != null) && (field.location.script == script)) {
- var a = new FieldDeclarationAnnotation(field, inspectLink(field));
- annotations.add(a);
- }
- }
- for (var cls in script.library.classes) {
- for (var field in cls.fields) {
- if ((field.location != null) && (field.location.script == script)) {
- var a = new FieldDeclarationAnnotation(field, inspectLink(field));
- annotations.add(a);
- }
- }
- }
- }
-
- void addFunctionAnnotations() {
- for (var func in script.library.functions) {
- if ((func.location != null) &&
- (func.location.script == script) &&
- (func.kind != M.FunctionKind.implicitGetter) &&
- (func.kind != M.FunctionKind.implicitSetter)) {
- // We annotate a field declaration with the field instead of the
- // implicit getter or setter.
- var a = new FunctionDeclarationAnnotation(func, inspectLink(func));
- annotations.add(a);
- }
- }
- for (var cls in script.library.classes) {
- for (var func in cls.functions) {
- if ((func.location != null) &&
- (func.location.script == script) &&
- (func.kind != M.FunctionKind.implicitGetter) &&
- (func.kind != M.FunctionKind.implicitSetter)) {
- // We annotate a field declaration with the field instead of the
- // implicit getter or setter.
- var a = new FunctionDeclarationAnnotation(func, inspectLink(func));
- annotations.add(a);
- }
- }
- }
- }
-
- void addCallSiteAnnotations() {
- for (var callSite in _callSites) {
- annotations.add(new CallSiteAnnotation(callSite));
- }
- }
-
- void addLocalVariableAnnotations() {
- // We have local variable information.
- if (variables != null) {
- // For each variable.
- for (var variable in variables) {
- // Find variable usage locations.
- var locations = script.scanForLocalVariableLocations(
- variable['name'],
- variable['_tokenPos'],
- variable['_endTokenPos']);
-
- // Annotate locations.
- for (var location in locations) {
- annotations.add(new LocalVariableAnnotation(location,
- variable['value']));
- }
- }
- }
- }
-
- int _buttonTop(Element element) {
- if (element == null) {
- return 5;
- }
- const padding = 5;
- // TODO (cbernaschina) check if this is needed.
- const navbarHeight = 40;
- var rect = getBoundingClientRect();
- var buttonHeight = element.clientHeight;
- return min(max(0, navbarHeight - rect.top) + padding,
- rect.height - (buttonHeight + padding));
- }
-
- RefreshButtonElement _newRefreshButton() {
- var button = new Element.tag('refresh-button');
- button.style.position = 'absolute';
- button.style.display = 'inline-block';
- button.style.top = '${_buttonTop(null)}px';
- button.style.right = '5px';
- button.callback = _refresh;
- button.title = 'Refresh coverage';
- return button;
- }
-
- ToggleButtonElement _newToggleProfileButton() {
- ToggleButtonElement button = new Element.tag('toggle-button');
- button.style.position = 'absolute';
- button.style.display = 'inline-block';
- button.style.top = '${_buttonTop(null)}px';
- button.style.right = '30px';
- button.title = 'Toggle CPU profile information';
- final String enabledColor = 'black';
- final String disabledColor = 'rgba(0, 0, 0 ,.3)';
- button.callback = (enabled) async {
- _includeProfile = enabled;
- if (button.children.length > 0) {
- var content = button.children[0];
- if (enabled) {
- content.style.color = enabledColor;
- } else {
- content.style.color = disabledColor;
- }
- }
- await update();
- };
- button.children.add(new Element.tag('icon-whatshot'));
- button.children[0].style.color = disabledColor;
- button.enabled = _includeProfile;
- return button;
- }
-
- Element linesTable() {
- var table = new DivElement();
- table.classes.add("sourceTable");
-
- _refreshButton = _newRefreshButton();
- _toggleProfileButton = _newToggleProfileButton();
- table.append(_refreshButton);
- table.append(_toggleProfileButton);
-
- if (_startLine == null || _endLine == null) {
- return table;
- }
-
- var endLine = (endPos != null
- ? script.tokenToLine(endPos)
- : script.lines.length + script.lineOffset);
- var lineNumPad = endLine.toString().length;
-
- annotationsCursor = 0;
-
- int blankLineCount = 0;
- for (int i = _startLine; i <= _endLine; i++) {
- var line = script.getLine(i);
- if (line.isBlank) {
- // Try to introduce elipses if there are 4 or more contiguous
- // blank lines.
- blankLineCount++;
- } else {
- if (blankLineCount > 0) {
- int firstBlank = i - blankLineCount;
- int lastBlank = i - 1;
- if (blankLineCount < 4) {
- // Too few blank lines for an elipsis.
- for (int j = firstBlank; j <= lastBlank; j++) {
- table.append(lineElement(script.getLine(j), lineNumPad));
- }
- } else {
- // Add an elipsis for the skipped region.
- table.append(lineElement(script.getLine(firstBlank), lineNumPad));
- table.append(lineElement(null, lineNumPad));
- table.append(lineElement(script.getLine(lastBlank), lineNumPad));
- }
- blankLineCount = 0;
- }
- table.append(lineElement(line, lineNumPad));
- }
- }
-
- return table;
- }
-
- // Assumes annotations are sorted.
- Annotation nextAnnotationOnLine(int line) {
- if (annotationsCursor >= annotations.length) return null;
- var annotation = annotations[annotationsCursor];
-
- // Fast-forward past any annotations before the first line that
- // we are displaying.
- while (annotation.line < line) {
- annotationsCursor++;
- if (annotationsCursor >= annotations.length) return null;
- annotation = annotations[annotationsCursor];
- }
-
- // Next annotation is for a later line, don't advance past it.
- if (annotation.line != line) return null;
- annotationsCursor++;
- return annotation;
- }
-
- Element lineElement(ScriptLine line, int lineNumPad) {
- var e = new DivElement();
- e.classes.add("sourceRow");
- e.append(lineBreakpointElement(line));
- e.append(lineNumberElement(line, lineNumPad));
- if (_includeProfile) {
- e.append(lineProfileElement(line, false));
- e.append(lineProfileElement(line, true));
- }
- e.append(lineSourceElement(line));
- return e;
- }
-
- Element lineProfileElement(ScriptLine line, bool self) {
- var e = span('');
- e.classes.add('noCopy');
- if (self) {
- e.title = 'Self %';
- } else {
- e.title = 'Total %';
- }
-
- if (line == null) {
- e.classes.add('notSourceProfile');
- e.text = nbsp;
- return e;
- }
-
- var ranges = _rangeMap[line.line];
- if ((ranges == null) || ranges.isEmpty) {
- e.classes.add('notSourceProfile');
- e.text = nbsp;
- return e;
- }
-
- ScriptLineProfile lineProfile = _profileMap[line.line];
- if (lineProfile == null) {
- e.classes.add('noProfile');
- e.text = nbsp;
- return e;
- }
-
- if (self) {
- e.text = lineProfile.formattedSelfTicks;
- } else {
- e.text = lineProfile.formattedTotalTicks;
- }
-
- if (lineProfile.isHot(self)) {
- e.classes.add('hotProfile');
- } else if (lineProfile.isMedium(self)) {
- e.classes.add('mediumProfile');
- } else {
- e.classes.add('coldProfile');
- }
-
- return e;
- }
-
- Element lineBreakpointElement(ScriptLine line) {
- var e = new DivElement();
- if (line == null || !_possibleBreakpointLines.contains(line.line)) {
- e.classes.add('noCopy');
- e.classes.add("emptyBreakpoint");
- e.text = nbsp;
- return e;
- }
-
- e.text = 'B';
- var busy = false;
- void update() {
- e.classes.clear();
- e.classes.add('noCopy');
- if (busy) {
- e.classes.add("busyBreakpoint");
- } else if (line.breakpoints != null) {
- bool resolved = false;
- for (var bpt in line.breakpoints) {
- if (bpt.resolved) {
- resolved = true;
- break;
- }
- }
- if (resolved) {
- e.classes.add("resolvedBreakpoint");
- } else {
- e.classes.add("unresolvedBreakpoint");
- }
- } else {
- e.classes.add("possibleBreakpoint");
- }
- }
-
- line.changes.listen((_) => update());
- e.onClick.listen((event) {
- if (busy) {
- return;
- }
- busy = true;
- if (line.breakpoints == null) {
- // No breakpoint. Add it.
- line.script.isolate.addBreakpoint(line.script, line.line)
- .catchError((e, st) {
- if (e is! ServerRpcException ||
- (e as ServerRpcException).code !=
- ServerRpcException.kCannotAddBreakpoint) {
- app.handleException(e, st);
- }})
- .whenComplete(() {
- busy = false;
- update();
- });
- } else {
- // Existing breakpoint. Remove it.
- List pending = [];
- for (var bpt in line.breakpoints) {
- pending.add(line.script.isolate.removeBreakpoint(bpt));
- }
- Future.wait(pending).then((_) {
- busy = false;
- update();
- });
- }
- update();
- });
- update();
- return e;
- }
-
- Element lineNumberElement(ScriptLine line, int lineNumPad) {
- var lineNumber = line == null ? "..." : line.line;
- var e = span("$nbsp${lineNumber.toString().padLeft(lineNumPad,nbsp)}$nbsp");
- e.classes.add('noCopy');
- if (lineNumber == _currentLine) {
- hitsCurrent(e);
- return e;
- }
- var ranges = _rangeMap[lineNumber];
- if ((ranges == null) || ranges.isEmpty) {
- // This line is not code.
- hitsUnknown(e);
- return e;
- }
- bool compiled = true;
- bool hasCallInfo = false;
- bool executed = false;
- for (var range in ranges) {
- if (range['compiled']) {
- for (var callSite in range['callSites']) {
- var callLine = line.script.tokenToLine(callSite['tokenPos']);
- if (lineNumber == callLine) {
- // The call site is on the current line.
- hasCallInfo = true;
- for (var cacheEntry in callSite['cacheEntries']) {
- if (cacheEntry['count'] > 0) {
- // If any call site on the line has been executed, we
- // mark the line as executed.
- executed = true;
- break;
- }
- }
- }
- }
- } else {
- // If any range isn't compiled, show the line as not compiled.
- // This is necessary so that nested functions appear to be uncompiled.
- compiled = false;
- }
- }
- if (executed) {
- hitsExecuted(e);
- } else if (hasCallInfo) {
- hitsNotExecuted(e);
- } else if (compiled) {
- hitsCompiled(e);
- } else {
- hitsNotCompiled(e);
- }
- return e;
- }
-
- Element lineSourceElement(ScriptLine line) {
- var e = new DivElement();
- e.classes.add("sourceItem");
-
- if (line != null) {
- if (line.line == _currentLine) {
- e.classes.add("currentLine");
- }
-
- e.id = makeLineId(line.line);
-
- var position = 0;
- consumeUntil(var stop) {
- if (stop <= position) {
- return null; // Empty gap between annotations/boundries.
- }
- if (stop > line.text.length) {
- // Approximated token length can run past the end of the line.
- stop = line.text.length;
- }
-
- var chunk = line.text.substring(position, stop);
- var chunkNode = span(chunk);
- e.append(chunkNode);
- position = stop;
- return chunkNode;
- }
-
- // TODO(rmacnak): Tolerate overlapping annotations.
- var annotation;
- while ((annotation = nextAnnotationOnLine(line.line)) != null) {
- consumeUntil(annotation.columnStart);
- annotation.applyStyleTo(consumeUntil(annotation.columnStop));
- }
- consumeUntil(line.text.length);
- }
-
- // So blank lines are included when copying script to the clipboard.
- e.append(span('\n'));
-
- return e;
- }
-
- ScriptInsetElement.created()
- : super.created() {
- _updateTask = new Task(update);
- }
-}
-
-@CustomTag('refresh-button')
-class RefreshButtonElement extends PolymerElement {
- RefreshButtonElement.created() : super.created();
-
- @published var callback = null;
- bool busy = false;
-
- Future buttonClick(var event, var b, var c) async {
- if (busy) {
- return;
- }
- busy = true;
- if (callback != null) {
- await callback();
- }
- busy = false;
- }
-}
-
-
-@CustomTag('toggle-button')
-class ToggleButtonElement extends PolymerElement {
- ToggleButtonElement.created() : super.created();
-
- @published var callback = null;
- @observable bool enabled = false;
-
- Future buttonClick(var event, var b, var c) async {
- enabled = !enabled;
- if (callback != null) {
- await callback(enabled);
- }
- }
-}
-
-
-@CustomTag('source-inset')
-class SourceInsetElement extends PolymerElement {
- SourceInsetElement.created() : super.created();
-
- @published SourceLocation location;
- @published String height = null;
- @published int currentPos;
- @published bool inDebuggerContext = false;
- @published ObservableList variables;
- @published Element scroller;
-}
diff --git a/runtime/observatory/lib/src/elements/script_inset.html b/runtime/observatory/lib/src/elements/script_inset.html
deleted file mode 100644
index c8ea9df..0000000
--- a/runtime/observatory/lib/src/elements/script_inset.html
+++ /dev/null
@@ -1,223 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-
-
-<polymer-element name="icon-refresh" noscript>
- <template>
- <style>
- svg {
- fill: currentColor
- }
- </style>
- <svg width="24" height="24">
- <path d="M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z"/>
- </svg>
- </template>
-</polymer-element>
-
-<polymer-element name="icon-whatshot" noscript>
- <template>
- <style>
- svg {
- fill: currentColor
- }
- </style>
- <svg width="24" height="24">
- <path d="M13.5.67s.74 2.65.74 4.8c0 2.06-1.35 3.73-3.41 3.73-2.07 0-3.63-1.67-3.63-3.73l.03-.36C5.21 7.51 4 10.62 4 14c0 4.42 3.58 8 8 8s8-3.58 8-8C20 8.61 17.41 3.8 13.5.67zM11.71 19c-1.78 0-3.22-1.4-3.22-3.14 0-1.62 1.05-2.76 2.81-3.12 1.77-.36 3.6-1.21 4.62-2.58.39 1.29.59 2.65.59 4.04 0 2.65-2.15 4.8-4.8 4.8z"></path>
- </svg>
- </template>
-</polymer-element>
-
-<polymer-element name="script-inset">
- <template>
- <style>
- a {
- color: #0489c3;
- text-decoration: none;
- }
- a:hover {
- text-decoration: underline;
- }
- .sourceInset {
- }
- .sourceTable {
- position: relative;
- background-color: #f5f5f5;
- border: 1px solid #ccc;
- padding: 10px;
- width: 100%;
- box-sizing: border-box;
- overflow-x: scroll;
- }
- .sourceRow {
- display: flex;
- flex-direction: row;
- width: 100%;
- }
- .sourceItem, .sourceItemCurrent {
- vertical-align: top;
- font: 400 14px consolas, courier, monospace;
- line-height: 125%;
- white-space: pre;
- max-width: 0;
- }
- .currentLine {
- background-color: #fff;
- }
- .currentCol {
- background-color: #6cf;
- }
- .hitsCurrent, .hitsNone, .hitsNotExecuted, .hitsExecuted, .hitsCompiled, .hitsNotCompiled {
- display: table-cell;
- vertical-align: top;
- font: 400 14px consolas, courier, monospace;
- margin-left: 5px;
- margin-right: 5px;
- text-align: right;
- color: #a8a8a8;
- }
- .hitsCurrent {
- background-color: #6cf;
- color: black;
- }
- .hitsNotExecuted {
- background-color: #faa;
- }
- .hitsExecuted {
- background-color: #aea;
- }
- .hitsCompiled {
- background-color: #e0e0e0;
- }
- .hitsNotCompiled {
- background-color: #f0c5c5;
- }
-
- .noCopy {}
- .emptyBreakpoint, .possibleBreakpoint, .busyBreakpoint, .unresolvedBreakpoint, .resolvedBreakpoint {
- display: table-cell;
- vertical-align: top;
- font: 400 14px consolas, courier, monospace;
- width: 1em;
- text-align: center;
- cursor: pointer;
- }
- .possibleBreakpoint {
- color: #e0e0e0;
- }
- .possibleBreakpoint:hover {
- color: white;
- background-color: #777;
- }
- .busyBreakpoint {
- color: white;
- background-color: black;
- cursor: wait;
- }
- .unresolvedBreakpoint {
- color: white;
- background-color: #cac;
- }
- .resolvedBreakpoint {
- color: white;
- background-color: #e66;
- }
- .unresolvedBreakAnnotation {
- color: white;
- background-color: #cac;
- }
- .resolvedBreakAnnotation {
- color: white;
- background-color: #e66;
- }
- .notSourceProfile, .noProfile, .coldProfile, .mediumProfile, .hotProfile {
- display: table-cell;
- vertical-align: top;
- font: 400 14px consolas, courier, monospace;
- width: 4em;
- text-align: right;
- cursor: pointer;
- margin-left: 5px;
- margin-right: 5px;
- }
- .notSourceProfile {
- }
- .noProfile {
- background-color: #e0e0e0;
- }
- .coldProfile {
- background-color: #aea;
- }
- .mediumProfile {
- background-color: #fe9;
- }
- .hotProfile {
- background-color: #faa;
- }
- </style>
- </template>
-</polymer-element>
-
-<polymer-element name="refresh-button">
- <template>
- <style>
- .refreshButton {
- color: rgba(0,0,0,.3);
- }
- .refreshButton:hover {
- color: black;
- }
- .refreshButtonDisabled {
- color: white;
- cursor: wait;
- }
- </style>
- <template if="{{ callback != null }}">
- <template if="{{ busy }}">
- <icon-refresh id="refreshIcon" class="refreshButtonDisabled">
- </icon-refresh>
- </template>
- <template if="{{ !busy }}">
- <a on-click="{{ buttonClick }}">
- <icon-refresh id="refreshIcon" class="refreshButton"></icon-refresh>
- </a>
- </template>
- </template>
- </template>
-</polymer-element>
-
-<polymer-element name="toggle-button">
- <template>
- <style>
- </style>
- <template if="{{ callback != null }}">
- <template if="{{ enabled }}">
- <a on-click="{{ buttonClick }}">
- <content></content>
- </a>
- </template>
- <template if="{{ !enabled }}">
- <a on-click="{{ buttonClick }}">
- <content></content>
- </a>
- </template>
- </template>
- </template>
-</polymer-element>
-
-<polymer-element name="source-inset">
-<template>
- <template if="{{ location != null }}">
- <script-inset script="{{ location.script }}"
- startPos="{{ location.tokenPos }}"
- scroller="{{ scroller }}"
- endPos="{{ location.endTokenPos }}"
- height="{{ height }}"
- currentPos="{{ currentPos }}"
- inDebuggerContext="{{ inDebuggerContext }}"
- variables="{{ variables }}">
- </script-inset>
- </template>
-</template>
-</polymer-element>
-
-<script type="application/dart" src="script_inset.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/script_inset_wrapper.dart b/runtime/observatory/lib/src/elements/script_inset_wrapper.dart
new file mode 100644
index 0000000..d3bcb68
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/script_inset_wrapper.dart
@@ -0,0 +1,265 @@
+// 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.
+
+import 'dart:html';
+import 'dart:async';
+
+import 'package:observatory/app.dart';
+import 'package:observatory/repositories.dart';
+import 'package:observatory/service_html.dart' show Script;
+import 'package:observatory/src/elements/script_inset.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/shims/binding.dart';
+
+@bindable
+class ScriptInsetElementWrapper extends HtmlElement {
+ static const binder = const Binder<ScriptInsetElementWrapper>(const {
+ 'script': #script, 'startpos': #startPos, 'endpos': #endPos,
+ 'currentpos': #currentPos, 'indebuggercontext': #inDebuggerContext,
+ 'variables': #variables, 'height': #height
+ });
+
+ static const tag = const Tag<ScriptInsetElementWrapper>('script-inset');
+
+ Script _script;
+ int _startPos;
+ int _endPos;
+ int _currentPos;
+ String _height;
+ bool _inDebuggerContext;
+ Iterable _variables;
+
+ Script get script => _script;
+ int get startPos => _startPos;
+ int get endPos => _endPos;
+ int get currentPos => _currentPos;
+ String get height => _height;
+ bool get inDebuggerContext => _inDebuggerContext;
+ Iterable get variables => _variables;
+
+ set script(Script value) {
+ _script = value;
+ render();
+ }
+ set startPos(int value) {
+ _startPos = value;
+ render();
+ }
+ set endPos(int value) {
+ _endPos = value;
+ render();
+ }
+ set currentPos(int value) {
+ _currentPos = value;
+ render();
+ }
+ set height(String value) {
+ _height = value;
+ render();
+ }
+ set inDebuggerContext(bool value) {
+ _inDebuggerContext = value;
+ render();
+ }
+ set variables(Iterable value) {
+ _variables = value;
+ render();
+ }
+
+ ScriptInsetElementWrapper.created() : super.created() {
+ binder.registerCallback(this);
+ createShadowRoot();
+ render();
+ }
+
+ @override
+ void attached() {
+ super.attached();
+ render();
+ }
+
+ Future render() async {
+ shadowRoot.children = [];
+ if (_script == null) {
+ return;
+ }
+
+ shadowRoot.children = [
+ new StyleElement()
+ ..text = '''
+ script-inset-wrapped {
+ position: relative;
+ }
+ script-inset-wrapped button.refresh,
+ script-inset-wrapped button.toggle-profile {
+ background-color: transparent;
+ padding: 0;
+ margin: 0;
+ border: none;
+ position: absolute;
+ display: inline-block;
+ top: 5px;
+ color: #888888;
+ line-height: 30px;
+ }
+ script-inset-wrapped button.refresh {
+ right: 5px;
+ font-size: 25px;
+ }
+ script-inset-wrapped button.toggle-profile {
+ right: 30px;
+ font-size: 20px;
+ }
+ script-inset-wrapped button.toggle-profile.enabled {
+ color: #BB3322;
+ }
+ script-inset-wrapped a {
+ color: #0489c3;
+ text-decoration: none;
+ }
+ script-inset-wrapped a:hover {
+ text-decoration: underline;
+ }
+ script-inset-wrapped .sourceInset {
+ }
+ script-inset-wrapped .sourceTable {
+ position: relative;
+ background-color: #f5f5f5;
+ border: 1px solid #ccc;
+ padding: 10px;
+ width: 100%;
+ box-sizing: border-box;
+ overflow-x: scroll;
+ }
+ script-inset-wrapped .sourceRow {
+ display: flex;
+ flex-direction: row;
+ width: 100%;
+ }
+ script-inset-wrapped .sourceItem,
+ script-inset-wrapped .sourceItemCurrent {
+ vertical-align: top;
+ font: 400 14px consolas, courier, monospace;
+ line-height: 125%;
+ white-space: pre;
+ max-width: 0;
+ }
+ script-inset-wrapped .currentLine {
+ background-color: #fff;
+ }
+ script-inset-wrapped .currentCol {
+ background-color: #6cf;
+ }
+ script-inset-wrapped .hitsCurrent,
+ script-inset-wrapped .hitsNone,
+ script-inset-wrapped .hitsNotExecuted,
+ script-inset-wrapped .hitsExecuted,
+ script-inset-wrapped .hitsCompiled,
+ script-inset-wrapped .hitsNotCompiled {
+ display: table-cell;
+ vertical-align: top;
+ font: 400 14px consolas, courier, monospace;
+ margin-left: 5px;
+ margin-right: 5px;
+ text-align: right;
+ color: #a8a8a8;
+ }
+ script-inset-wrapped .hitsCurrent {
+ background-color: #6cf;
+ color: black;
+ }
+ script-inset-wrapped .hitsNotExecuted {
+ background-color: #faa;
+ }
+ script-inset-wrapped .hitsExecuted {
+ background-color: #aea;
+ }
+ script-inset-wrapped .hitsCompiled {
+ background-color: #e0e0e0;
+ }
+ script-inset-wrapped .hitsNotCompiled {
+ background-color: #f0c5c5;
+ }
+ script-inset-wrapped .noCopy {}
+ script-inset-wrapped .emptyBreakpoint,
+ script-inset-wrapped .possibleBreakpoint,
+ script-inset-wrapped .busyBreakpoint,
+ script-inset-wrapped .unresolvedBreakpoint,
+ script-inset-wrapped .resolvedBreakpoint {
+ display: table-cell;
+ vertical-align: top;
+ font: 400 14px consolas, courier, monospace;
+ width: 1em;
+ text-align: center;
+ cursor: pointer;
+ }
+ script-inset-wrapped .possibleBreakpoint {
+ color: #e0e0e0;
+ }
+ script-inset-wrapped .possibleBreakpoint:hover {
+ color: white;
+ background-color: #777;
+ }
+ script-inset-wrapped .busyBreakpoint {
+ color: white;
+ background-color: black;
+ cursor: wait;
+ }
+ script-inset-wrapped .unresolvedBreakpoint {
+ color: white;
+ background-color: #cac;
+ }
+ script-inset-wrapped .resolvedBreakpoint {
+ color: white;
+ background-color: #e66;
+ }
+ script-inset-wrapped .unresolvedBreakAnnotation {
+ color: white;
+ background-color: #cac;
+ }
+ script-inset-wrapped .resolvedBreakAnnotation {
+ color: white;
+ background-color: #e66;
+ }
+ script-inset-wrapped .notSourceProfile,
+ script-inset-wrapped .noProfile,
+ script-inset-wrapped .coldProfile,
+ script-inset-wrapped .mediumProfile,
+ script-inset-wrapped .hotProfile {
+ display: table-cell;
+ vertical-align: top;
+ font: 400 14px consolas, courier, monospace;
+ width: 4em;
+ text-align: right;
+ cursor: pointer;
+ margin-left: 5px;
+ margin-right: 5px;
+ }
+ script-inset-wrapped .notSourceProfile {
+ }
+ script-inset-wrapped .noProfile {
+ background-color: #e0e0e0;
+ }
+ script-inset-wrapped .coldProfile {
+ background-color: #aea;
+ }
+ script-inset-wrapped .mediumProfile {
+ background-color: #fe9;
+ }
+ script-inset-wrapped .hotProfile {
+ background-color: #faa;
+ }''',
+ new ScriptInsetElement(_script.isolate, _script,
+ new ScriptRepository(),
+ new InstanceRepository(),
+ ObservatoryApplication.app.events,
+ startPos: _startPos,
+ endPos: _endPos,
+ currentPos: _currentPos,
+ inDebuggerContext: _inDebuggerContext ?? false,
+ variables: _variables ?? const [],
+ queue: ObservatoryApplication.app.queue)
+ ];
+ }
+}
diff --git a/runtime/observatory/lib/src/elements/script_view.dart b/runtime/observatory/lib/src/elements/script_view.dart
index c896b8d..fd763f4 100644
--- a/runtime/observatory/lib/src/elements/script_view.dart
+++ b/runtime/observatory/lib/src/elements/script_view.dart
@@ -2,22 +2,163 @@
// 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_view_element;
+library script_view;
import 'dart:async';
-import 'observatory_element.dart';
-import 'package:observatory/elements.dart';
-import 'package:observatory/service.dart';
-import 'package:polymer/polymer.dart';
+import 'dart:html';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/context_ref.dart';
+import 'package:observatory/src/elements/curly_block.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/nav/bar.dart';
+import 'package:observatory/src/elements/nav/isolate_menu.dart';
+import 'package:observatory/src/elements/nav/library_menu.dart';
+import 'package:observatory/src/elements/nav/menu.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import 'package:observatory/src/elements/nav/refresh.dart';
+import 'package:observatory/src/elements/nav/top_menu.dart';
+import 'package:observatory/src/elements/nav/vm_menu.dart';
+import 'package:observatory/src/elements/object_common.dart';
+import 'package:observatory/src/elements/script_inset.dart';
+import 'package:observatory/src/elements/view_footer.dart';
-/// Displays an Script response.
-@CustomTag('script-view')
-class ScriptViewElement extends ObservatoryElement {
- @published Script script;
+class ScriptViewElement extends HtmlElement implements Renderable {
+ static const tag = const Tag<ScriptViewElement>('script-view',
+ dependencies: const [
+ ContextRefElement.tag,
+ CurlyBlockElement.tag,
+ NavBarElement.tag,
+ NavTopMenuElement.tag,
+ NavVMMenuElement.tag,
+ NavIsolateMenuElement.tag,
+ NavLibraryMenuElement.tag,
+ NavMenuElement.tag,
+ NavRefreshElement.tag,
+ NavNotifyElement.tag,
+ ObjectCommonElement.tag,
+ ScriptInsetElement.tag,
+ ViewFooterElement.tag
+ ]);
+
+ RenderingScheduler<ScriptViewElement> _r;
+
+ Stream<RenderedEvent<ScriptViewElement>> get onRendered =>
+ _r.onRendered;
+
+ M.VM _vm;
+ M.IsolateRef _isolate;
+ M.EventRepository _events;
+ M.NotificationRepository _notifications;
+ M.Script _script;
+ M.ScriptRepository _scripts;
+ M.RetainedSizeRepository _retainedSizes;
+ M.ReachableSizeRepository _reachableSizes;
+ M.InboundReferencesRepository _references;
+ M.RetainingPathRepository _retainingPaths;
+ M.InstanceRepository _instances;
+ int _pos;
+
+
+ M.VMRef get vm => _vm;
+ M.IsolateRef get isolate => _isolate;
+ M.NotificationRepository get notifications => _notifications;
+ M.Script get script => _script;
+
+ factory ScriptViewElement(M.VM vm, M.IsolateRef isolate,
+ M.Script script,
+ M.EventRepository events,
+ M.NotificationRepository notifications,
+ M.ScriptRepository scripts,
+ M.RetainedSizeRepository retainedSizes,
+ M.ReachableSizeRepository reachableSizes,
+ M.InboundReferencesRepository references,
+ M.RetainingPathRepository retainingPaths,
+ M.InstanceRepository instances,
+ {int pos, RenderingQueue queue}) {
+ assert(vm != null);
+ assert(isolate != null);
+ assert(events != null);
+ assert(notifications != null);
+ assert(script != null);
+ assert(scripts != null);
+ assert(retainedSizes != null);
+ assert(reachableSizes != null);
+ assert(references != null);
+ assert(retainingPaths != null);
+ assert(instances != null);
+ ScriptViewElement e = document.createElement(tag.name);
+ e._r = new RenderingScheduler(e, queue: queue);
+ e._vm = vm;
+ e._isolate = isolate;
+ e._events = events;
+ e._notifications = notifications;
+ e._script = script;
+ e._scripts = scripts;
+ e._retainedSizes = retainedSizes;
+ e._reachableSizes = reachableSizes;
+ e._references = references;
+ e._retainingPaths = retainingPaths;
+ e._instances = instances;
+ e._pos = pos;
+ return e;
+ }
ScriptViewElement.created() : super.created();
- Future refresh() {
- return script.reload();
+ @override
+ attached() {
+ super.attached();
+ _r.enable();
+ }
+
+ @override
+ detached() {
+ super.detached();
+ _r.disable(notify: true);
+ children = [];
+ }
+
+ void render() {
+ children = [
+ new NavBarElement(queue: _r.queue)
+ ..children = [
+ new NavTopMenuElement(queue: _r.queue),
+ new NavVMMenuElement(_vm, _events, queue: _r.queue),
+ new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+ new NavLibraryMenuElement(_isolate, _script.library, queue: _r.queue),
+ new NavMenuElement('object', last: true, queue: _r.queue),
+ new NavRefreshElement(queue: _r.queue)
+ ..onRefresh.listen((e) async {
+ e.element.disabled = true;
+ _script = await _scripts.get(_isolate, _script.id);
+ _r.dirty();
+ }),
+ new NavNotifyElement(_notifications, queue: _r.queue)
+ ],
+ new DivElement()..classes = const ['content-centered-big']
+ ..children = [
+ new HeadingElement.h2()..text = 'Script',
+ new HRElement(),
+ new ObjectCommonElement(_isolate, _script, _retainedSizes,
+ _reachableSizes, _references, _retainingPaths,
+ _instances, queue: _r.queue),
+ new BRElement(),
+ new DivElement()..classes = ['memberList']
+ ..children = [
+ new DivElement()..classes = ['memberItem']
+ ..children = [
+ new DivElement()..classes = ['memberName']
+ ..text = 'load time',
+ new DivElement()..classes = ['memberName']
+ ..text = '${_script.loadTime}'
+ ],
+ ],
+ new HRElement(),
+ new ScriptInsetElement(_isolate, _script, _scripts, _instances,
+ _events, currentPos: _pos, queue: _r.queue),
+ new ViewFooterElement(queue: _r.queue)
+ ]
+ ];
}
}
diff --git a/runtime/observatory/lib/src/elements/script_view.html b/runtime/observatory/lib/src/elements/script_view.html
deleted file mode 100644
index b732128..0000000
--- a/runtime/observatory/lib/src/elements/script_view.html
+++ /dev/null
@@ -1,39 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="script_inset.html">
-
-<polymer-element name="script-view">
-<template>
- <link rel="stylesheet" href="css/shared.css">
- <nav-bar>
- <top-nav-menu></top-nav-menu>
- <vm-nav-menu vm="{{ script.isolate.vm }}"></vm-nav-menu>
- <isolate-nav-menu isolate="{{ script.isolate }}"></isolate-nav-menu>
- <library-nav-menu library="{{ script.library }}"></library-nav-menu>
- <nav-menu link="{{ makeLink('/inspect', script) }}" anchor="{{ script.name }}" last="{{ true }}"></nav-menu>
- <nav-refresh callback="{{ refresh }}"></nav-refresh>
- <nav-notify notifications="{{ app.notifications }}"></nav-notify>
- </nav-bar>
-
- <div class="content-centered-big">
- <h1>script {{ script.name }}</h1>
- <object-common object="{{ script }}"></object-common>
- <br>
-
- <div class="memberList">
- <div class="memberItem">
- <div class="memberName">loaded at</div>
- <div class="memberValue">{{ script.loadTime.toString() }}</div>
- </div>
- </div>
-
- <hr>
- <script-inset id="scriptInset" script="{{ script }}"
- currentPos="{{ app.locationManager.internalArguments['pos'] | parseInt }}">
- </script-inset>
- </div>
-
- <view-footer></view-footer>
-</template>
-</polymer-element>
-
-<script type="application/dart" src="script_view.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/service_view.dart b/runtime/observatory/lib/src/elements/service_view.dart
index 6bf3808..6cd9a3e 100644
--- a/runtime/observatory/lib/src/elements/service_view.dart
+++ b/runtime/observatory/lib/src/elements/service_view.dart
@@ -30,34 +30,9 @@
CodeViewElement element = new Element.tag('code-view');
element.code = object;
return element;
- case 'Error':
- ErrorViewElement element = new Element.tag('error-view');
- element.error = object;
- return element;
- case 'Field':
- FieldViewElement element = new Element.tag('field-view');
- element.field = object;
- return element;
- case 'Function':
- FunctionViewElement element = new Element.tag('function-view');
- element.function = object;
- return element;
- case 'HeapMap':
- HeapMapElement element = new Element.tag('heap-map');
- element.fragmentation = object;
- return element;
case 'Object':
return (object) {
switch (object.vmType) {
- case 'MegamorphicCache':
- MegamorphicCacheViewElement element =
- new Element.tag('megamorphiccache-view');
- element.megamorphicCache = object;
- return element;
- case 'ObjectPool':
- ObjectPoolViewElement element = new Element.tag('objectpool-view');
- element.pool = object;
- return element;
default:
ObjectViewElement element = new Element.tag('object-view');
element.object = object;
@@ -72,10 +47,6 @@
LibraryViewElement element = new Element.tag('library-view');
element.library = object;
return element;
- case 'Script':
- ScriptViewElement element = new Element.tag('script-view');
- element.script = object;
- return element;
case 'VM':
VMViewElement element = new Element.tag('vm-view');
element.vm = object;
diff --git a/runtime/observatory/lib/src/elements/service_view.html b/runtime/observatory/lib/src/elements/service_view.html
index 6bd7e63..8b9b559 100644
--- a/runtime/observatory/lib/src/elements/service_view.html
+++ b/runtime/observatory/lib/src/elements/service_view.html
@@ -1,13 +1,8 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
<link rel="import" href="class_view.html">
<link rel="import" href="code_view.html">
-<link rel="import" href="error_view.html">
-<link rel="import" href="field_view.html">
-<link rel="import" href="function_view.html">
-<link rel="import" href="heap_map.html">
<link rel="import" href="instance_view.html">
<link rel="import" href="library_view.html">
-<link rel="import" href="script_view.html">
<link rel="import" href="vm_view.html">
<polymer-element name="service-view">
<!-- This element explicitly manages the child elements to avoid setting
diff --git a/runtime/observatory/lib/src/elements/source_inset.dart b/runtime/observatory/lib/src/elements/source_inset.dart
new file mode 100644
index 0000000..b62376a
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/source_inset.dart
@@ -0,0 +1,89 @@
+// 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 source_inset_element;
+
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/script_inset.dart';
+
+class SourceInsetElement extends HtmlElement implements Renderable {
+ static const tag = const Tag<SourceInsetElement>('source-inset-wrapped');
+
+ RenderingScheduler _r;
+
+ Stream<RenderedEvent<SourceInsetElement>> get onRendered => _r.onRendered;
+
+
+ M.IsolateRef _isolate;
+ M.SourceLocation _location;
+ M.ScriptRepository _scripts;
+ M.InstanceRepository _instances;
+ M.EventRepository _events;
+ int _currentPos;
+ bool _inDebuggerContext;
+ Iterable _variables;
+
+ M.IsolateRef get isolate => _isolate;
+ M.SourceLocation get location => _location;
+
+ factory SourceInsetElement(M.IsolateRef isolate, M.SourceLocation location,
+ M.ScriptRepository scripts,
+ M.InstanceRepository instances,
+ M.EventRepository events,
+ {int currentPos,
+ bool inDebuggerContext: false,
+ Iterable variables: const [],
+ RenderingQueue queue}) {
+ assert(isolate != null);
+ assert(location != null);
+ assert(scripts != null);
+ assert(instances != null);
+ assert(events != null);
+ assert(inDebuggerContext != null);
+ assert(variables != null);
+ SourceInsetElement e = document.createElement(tag.name);
+ e._r = new RenderingScheduler(e, queue: queue);
+ e._isolate = isolate;
+ e._location = location;
+ e._scripts = scripts;
+ e._instances = instances;
+ e._events = events;
+ e._currentPos = currentPos;
+ e._inDebuggerContext = inDebuggerContext;
+ e._variables = variables;
+ return e;
+ }
+
+ SourceInsetElement.created() : super.created();
+
+ @override
+ void attached() {
+ super.attached();
+ _r.enable();
+ }
+
+ @override
+ void detached() {
+ super.detached();
+ children = [];
+ _r.disable(notify: true);
+ }
+
+ void render() {
+ children = [
+ new ScriptInsetElement(_isolate, _location.script,
+ _scripts, _instances, _events,
+ startPos: _location.tokenPos,
+ endPos: _location.endTokenPos,
+ currentPos: _currentPos,
+ inDebuggerContext: _inDebuggerContext,
+ variables: _variables,
+ queue: _r.queue)
+ ];
+ }
+}
diff --git a/runtime/observatory/lib/src/elements/source_inset_wrapper.dart b/runtime/observatory/lib/src/elements/source_inset_wrapper.dart
new file mode 100644
index 0000000..49292d6
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/source_inset_wrapper.dart
@@ -0,0 +1,246 @@
+// 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.
+
+import 'dart:html';
+import 'dart:async';
+
+import 'package:observatory/app.dart';
+import 'package:observatory/repositories.dart';
+import 'package:observatory/service_html.dart' show SourceLocation;
+import 'package:observatory/src/elements/script_inset.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/shims/binding.dart';
+
+@bindable
+class SourceInsetElementWrapper extends HtmlElement {
+ static const binder = const Binder<SourceInsetElementWrapper>(const {
+ 'location': #location, 'currentpos': #currentPos,
+ 'indebuggercontext': #inDebuggerContext, 'variables': #variables
+ });
+
+ static const tag = const Tag<SourceInsetElementWrapper>('source-inset');
+
+ SourceLocation _location;
+ int _currentPos;
+ bool _inDebuggerContext;
+ Iterable _variables;
+
+ SourceLocation get location => _location;
+ int get currentPos => _currentPos;
+ bool get inDebuggerContext => _inDebuggerContext;
+ Iterable get variables => _variables;
+
+ set location(SourceLocation value) {
+ _location = value;
+ render();
+ }
+ set currentPos(int value) {
+ _currentPos = value;
+ render();
+ }
+ set inDebuggerContext(bool value) {
+ _inDebuggerContext = value;
+ render();
+ }
+ set variables(Iterable value) {
+ _variables = value;
+ render();
+ }
+
+ SourceInsetElementWrapper.created() : super.created() {
+ binder.registerCallback(this);
+ createShadowRoot();
+ render();
+ }
+
+ @override
+ void attached() {
+ super.attached();
+ render();
+ }
+
+ Future render() async {
+ shadowRoot.children = [];
+ if (_location == null) {
+ return;
+ }
+
+ shadowRoot.children = [
+ new StyleElement()
+ ..text = '''
+ script-inset-wrapped {
+ position: relative;
+ }
+ script-inset-wrapped button.refresh,
+ script-inset-wrapped button.toggle-profile {
+ background-color: transparent;
+ padding: 0;
+ margin: 0;
+ border: none;
+ position: absolute;
+ display: inline-block;
+ top: 5px;
+ color: #888888;
+ line-height: 30px;
+ }
+ script-inset-wrapped button.refresh {
+ right: 5px;
+ font-size: 25px;
+ }
+ script-inset-wrapped button.toggle-profile {
+ right: 30px;
+ font-size: 20px;
+ }
+ script-inset-wrapped button.toggle-profile.enabled {
+ color: #BB3322;
+ }
+ script-inset-wrapped a {
+ color: #0489c3;
+ text-decoration: none;
+ }
+ script-inset-wrapped a:hover {
+ text-decoration: underline;
+ }
+ script-inset-wrapped .sourceInset {
+ }
+ script-inset-wrapped .sourceTable {
+ position: relative;
+ background-color: #f5f5f5;
+ border: 1px solid #ccc;
+ padding: 10px;
+ width: 100%;
+ box-sizing: border-box;
+ overflow-x: scroll;
+ }
+ script-inset-wrapped .sourceRow {
+ display: flex;
+ flex-direction: row;
+ width: 100%;
+ }
+ script-inset-wrapped .sourceItem,
+ script-inset-wrapped .sourceItemCurrent {
+ vertical-align: top;
+ font: 400 14px consolas, courier, monospace;
+ line-height: 125%;
+ white-space: pre;
+ max-width: 0;
+ }
+ script-inset-wrapped .currentLine {
+ background-color: #fff;
+ }
+ script-inset-wrapped .currentCol {
+ background-color: #6cf;
+ }
+ script-inset-wrapped .hitsCurrent,
+ script-inset-wrapped .hitsNone,
+ script-inset-wrapped .hitsNotExecuted,
+ script-inset-wrapped .hitsExecuted,
+ script-inset-wrapped .hitsCompiled,
+ script-inset-wrapped .hitsNotCompiled {
+ display: table-cell;
+ vertical-align: top;
+ font: 400 14px consolas, courier, monospace;
+ margin-left: 5px;
+ margin-right: 5px;
+ text-align: right;
+ color: #a8a8a8;
+ }
+ script-inset-wrapped .hitsCurrent {
+ background-color: #6cf;
+ color: black;
+ }
+ script-inset-wrapped .hitsNotExecuted {
+ background-color: #faa;
+ }
+ script-inset-wrapped .hitsExecuted {
+ background-color: #aea;
+ }
+ script-inset-wrapped .hitsCompiled {
+ background-color: #e0e0e0;
+ }
+ script-inset-wrapped .hitsNotCompiled {
+ background-color: #f0c5c5;
+ }
+ script-inset-wrapped .noCopy {}
+ script-inset-wrapped .emptyBreakpoint,
+ script-inset-wrapped .possibleBreakpoint,
+ script-inset-wrapped .busyBreakpoint,
+ script-inset-wrapped .unresolvedBreakpoint,
+ script-inset-wrapped .resolvedBreakpoint {
+ display: table-cell;
+ vertical-align: top;
+ font: 400 14px consolas, courier, monospace;
+ width: 1em;
+ text-align: center;
+ cursor: pointer;
+ }
+ script-inset-wrapped .possibleBreakpoint {
+ color: #e0e0e0;
+ }
+ script-inset-wrapped .possibleBreakpoint:hover {
+ color: white;
+ background-color: #777;
+ }
+ script-inset-wrapped .busyBreakpoint {
+ color: white;
+ background-color: black;
+ cursor: wait;
+ }
+ script-inset-wrapped .unresolvedBreakpoint {
+ color: white;
+ background-color: #cac;
+ }
+ script-inset-wrapped .resolvedBreakpoint {
+ color: white;
+ background-color: #e66;
+ }
+ script-inset-wrapped .unresolvedBreakAnnotation {
+ color: white;
+ background-color: #cac;
+ }
+ script-inset-wrapped .resolvedBreakAnnotation {
+ color: white;
+ background-color: #e66;
+ }
+ script-inset-wrapped .notSourceProfile,
+ script-inset-wrapped .noProfile,
+ script-inset-wrapped .coldProfile,
+ script-inset-wrapped .mediumProfile,
+ script-inset-wrapped .hotProfile {
+ display: table-cell;
+ vertical-align: top;
+ font: 400 14px consolas, courier, monospace;
+ width: 4em;
+ text-align: right;
+ cursor: pointer;
+ margin-left: 5px;
+ margin-right: 5px;
+ }
+ script-inset-wrapped .notSourceProfile {
+ }
+ script-inset-wrapped .noProfile {
+ background-color: #e0e0e0;
+ }
+ script-inset-wrapped .coldProfile {
+ background-color: #aea;
+ }
+ script-inset-wrapped .mediumProfile {
+ background-color: #fe9;
+ }
+ script-inset-wrapped .hotProfile {
+ background-color: #faa;
+ }''',
+ new ScriptInsetElement(_location.script.isolate, _location.script,
+ new ScriptRepository(),
+ new InstanceRepository(),
+ ObservatoryApplication.app.events,
+ startPos: _location.tokenPos,
+ endPos: _location.endTokenPos,
+ currentPos: _currentPos,
+ inDebuggerContext: _inDebuggerContext ?? false,
+ variables: _variables ?? const [],
+ queue: ObservatoryApplication.app.queue)
+ ];
+ }
+}
diff --git a/runtime/observatory/lib/src/elements/source_link.dart b/runtime/observatory/lib/src/elements/source_link.dart
index 110b8e1..ca65709 100644
--- a/runtime/observatory/lib/src/elements/source_link.dart
+++ b/runtime/observatory/lib/src/elements/source_link.dart
@@ -44,7 +44,7 @@
@override
void attached() {
super.attached();
- _repository.get(_location.script.id).then((script) {
+ _repository.get(_isolate, _location.script.id).then((script) {
_script = script;
_r.dirty();
});
diff --git a/runtime/observatory/lib/src/elements/source_link_wrapper.dart b/runtime/observatory/lib/src/elements/source_link_wrapper.dart
index 20221ea..199f949 100644
--- a/runtime/observatory/lib/src/elements/source_link_wrapper.dart
+++ b/runtime/observatory/lib/src/elements/source_link_wrapper.dart
@@ -45,8 +45,6 @@
return;
}
- ScriptRepository repository = new ScriptRepository(_location.isolate);
-
shadowRoot.children = [
new StyleElement()
..text = '''
@@ -57,7 +55,8 @@
color: #0489c3;
text-decoration: none;
}''',
- new SourceLinkElement(_location.isolate, _location, repository,
+ new SourceLinkElement(_location.isolate, _location,
+ new ScriptRepository(),
queue: ObservatoryApplication.app.queue)
];
}
diff --git a/runtime/observatory/lib/src/elements/vm_view.html b/runtime/observatory/lib/src/elements/vm_view.html
index 1a5481b..84738a2 100644
--- a/runtime/observatory/lib/src/elements/vm_view.html
+++ b/runtime/observatory/lib/src/elements/vm_view.html
@@ -1,5 +1,4 @@
<link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="eval_box.html">
<link rel="import" href="isolate_summary.html">
<polymer-element name="vm-view">
diff --git a/runtime/observatory/lib/src/models/objects/breakpoint.dart b/runtime/observatory/lib/src/models/objects/breakpoint.dart
index daf1277..de9e65a 100644
--- a/runtime/observatory/lib/src/models/objects/breakpoint.dart
+++ b/runtime/observatory/lib/src/models/objects/breakpoint.dart
@@ -7,7 +7,12 @@
abstract class Breakpoint extends Object {
/// A number identifying this breakpoint to the user.
int get number;
-
/// Has this breakpoint been assigned to a specific program location?
bool get resolved;
+ /// [optional]Is this a breakpoint that was added synthetically as part of a
+ /// step OverAsyncSuspension resume command?
+ bool get isSyntheticAsyncContinuation;
+ /// SourceLocation when breakpoint is resolved, UnresolvedSourceLocation
+ /// when a breakpoint is not resolved.
+ Location get location;
}
diff --git a/runtime/observatory/lib/src/models/objects/error.dart b/runtime/observatory/lib/src/models/objects/error.dart
index 8b36aed..06c6e61 100644
--- a/runtime/observatory/lib/src/models/objects/error.dart
+++ b/runtime/observatory/lib/src/models/objects/error.dart
@@ -17,7 +17,6 @@
}
abstract class ErrorRef extends ObjectRef {
- String get id;
ErrorKind get kind;
String get message;
}
diff --git a/runtime/observatory/lib/src/models/objects/field.dart b/runtime/observatory/lib/src/models/objects/field.dart
index 152c920..188f223 100644
--- a/runtime/observatory/lib/src/models/objects/field.dart
+++ b/runtime/observatory/lib/src/models/objects/field.dart
@@ -27,3 +27,21 @@
/// Is this field static?
bool get isStatic;
}
+
+enum GuardClassKind {
+ unknown,
+ single,
+ dynamic
+}
+
+abstract class Field extends Object implements FieldRef {
+ /// [optional] The value of this field, if the field is static.
+ InstanceRef get staticValue;
+
+ /// [optional] The location of this field in the source code.
+ SourceLocation get location;
+
+ GuardClassKind get guardClassKind;
+ ClassRef get guardClass;
+ bool get guardNullable;
+}
diff --git a/runtime/observatory/lib/src/models/objects/function.dart b/runtime/observatory/lib/src/models/objects/function.dart
index 933954f..f73f0db 100644
--- a/runtime/observatory/lib/src/models/objects/function.dart
+++ b/runtime/observatory/lib/src/models/objects/function.dart
@@ -82,4 +82,17 @@
/// The compiled code associated with this function. [optional]
CodeRef get code;
+ /// [optional]
+ CodeRef get unoptimizedCode;
+ /// [optional]
+ FieldRef get field;
+ int get usageCounter;
+ InstanceRef get icDataArray;
+ int get deoptimizations;
+ bool get isOptimizable;
+ bool get isInlinable;
+ bool get hasIntrinsic;
+ bool get isRecognized;
+ bool get isNative;
+ String get vmName;
}
diff --git a/runtime/observatory/lib/src/models/objects/library.dart b/runtime/observatory/lib/src/models/objects/library.dart
index 281242a..602231c 100644
--- a/runtime/observatory/lib/src/models/objects/library.dart
+++ b/runtime/observatory/lib/src/models/objects/library.dart
@@ -14,7 +14,7 @@
abstract class Library extends Object implements LibraryRef {
/// Is this library debuggable? Default true.
- bool get debuggable;
+ //bool get debuggable;
/// A list of the imports for this library.
//LibraryDependency[] dependencies;
diff --git a/runtime/observatory/lib/src/models/objects/megamorphiccache.dart b/runtime/observatory/lib/src/models/objects/megamorphiccache.dart
index a87fb48..74657de 100644
--- a/runtime/observatory/lib/src/models/objects/megamorphiccache.dart
+++ b/runtime/observatory/lib/src/models/objects/megamorphiccache.dart
@@ -7,3 +7,10 @@
abstract class MegamorphicCacheRef extends ObjectRef {
String get selector;
}
+
+abstract class MegamorphicCache extends Object implements MegamorphicCacheRef {
+ String get selector;
+ int get mask;
+ InstanceRef get buckets;
+ InstanceRef get argumentsDescriptor;
+}
diff --git a/runtime/observatory/lib/src/models/objects/objectpool.dart b/runtime/observatory/lib/src/models/objects/objectpool.dart
index c9be553..1f0b738 100644
--- a/runtime/observatory/lib/src/models/objects/objectpool.dart
+++ b/runtime/observatory/lib/src/models/objects/objectpool.dart
@@ -7,3 +7,20 @@
abstract class ObjectPoolRef extends ObjectRef {
int get length;
}
+
+abstract class ObjectPool extends Object implements ObjectPoolRef {
+ Iterable<ObjectPoolEntry> get entries;
+}
+
+enum ObjectPoolEntryKind {
+ object,
+ immediate,
+ nativeEntry
+}
+
+abstract class ObjectPoolEntry {
+ int get offset;
+ ObjectPoolEntryKind get kind;
+ ObjectRef get asObject;
+ int get asInteger;
+}
diff --git a/runtime/observatory/lib/src/models/objects/objectstore.dart b/runtime/observatory/lib/src/models/objects/objectstore.dart
new file mode 100644
index 0000000..694f858
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/objectstore.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of models;
+
+abstract class ObjectStore {
+ Iterable<NamedField> get fields;
+}
+
+abstract class NamedField {
+ String get name;
+ ObjectRef get value;
+}
diff --git a/runtime/observatory/lib/src/models/objects/persistent_handles.dart b/runtime/observatory/lib/src/models/objects/persistent_handles.dart
new file mode 100644
index 0000000..ff81ff2
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/persistent_handles.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of models;
+
+abstract class PersistentHandles {
+ Iterable<PersistentHandle> get elements;
+ Iterable<WeakPersistentHandle> get weakElements;
+}
+
+abstract class PersistentHandle {
+ ObjectRef get object;
+}
+
+abstract class WeakPersistentHandle implements PersistentHandle {
+ int get externalSize;
+ String get peer;
+ String get callbackSymbolName;
+ String get callbackAddress;
+}
diff --git a/runtime/observatory/lib/src/models/objects/script.dart b/runtime/observatory/lib/src/models/objects/script.dart
index 3736651..df4b63b 100644
--- a/runtime/observatory/lib/src/models/objects/script.dart
+++ b/runtime/observatory/lib/src/models/objects/script.dart
@@ -11,12 +11,18 @@
abstract class Script extends Object implements ScriptRef {
/// The library which owns this script.
- // LibraryRef get library;
+ LibraryRef get library;
/// The source code for this script. For certain built-in scripts,
/// this may be reconstructed without source comments.
String get source;
+ DateTime get loadTime;
+ int get firstTokenPos;
+ int get lastTokenPos;
+ int get lineOffset;
+ int get columnOffset;
+
int tokenToLine(int token);
int tokenToCol(int token);
}
diff --git a/runtime/observatory/lib/src/models/objects/source_location.dart b/runtime/observatory/lib/src/models/objects/source_location.dart
index dd9f663..5fc8b6c 100644
--- a/runtime/observatory/lib/src/models/objects/source_location.dart
+++ b/runtime/observatory/lib/src/models/objects/source_location.dart
@@ -4,11 +4,28 @@
part of models;
-abstract class SourceLocation {
+abstract class Location {
/// The script containing the source location.
ScriptRef get script;
- /// The first token of the location.
+ /// The last token of the location if this is a range. [optional]
+ int get tokenPos;
+}
+
+abstract class SourceLocation implements Location {
+ /// The last token of the location if this is a range.
int get tokenPos;
/// The last token of the location if this is a range. [optional]
int get endTokenPos;
}
+
+abstract class UnresolvedSourceLocation implements Location {
+ // [optional] The uri of the script containing the source location if the
+ // script has yet to be loaded.
+ String get scriptUri;
+ /// [optional] An approximate line number for the source location. This may
+ /// change when the location is resolved.
+ int get line;
+ /// [optional] An approximate column number for the source location. This may
+ /// change when the location is resolved.
+ int get column;
+}
diff --git a/runtime/observatory/lib/src/models/repositories/class.dart b/runtime/observatory/lib/src/models/repositories/class.dart
index 388256e..6394377 100644
--- a/runtime/observatory/lib/src/models/repositories/class.dart
+++ b/runtime/observatory/lib/src/models/repositories/class.dart
@@ -5,6 +5,6 @@
part of models;
abstract class ClassRepository{
- Future<Class> getObject();
- Future<Class> get(String id);
+ Future<Class> getObject(IsolateRef isolate);
+ Future<Class> get(IsolateRef isolate, String id);
}
diff --git a/runtime/observatory/lib/src/models/repositories/eval.dart b/runtime/observatory/lib/src/models/repositories/eval.dart
new file mode 100644
index 0000000..af38e4e
--- /dev/null
+++ b/runtime/observatory/lib/src/models/repositories/eval.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+part of models;
+
+abstract class EvalRepository{
+ Future<ObjectRef> evaluate(IsolateRef isolate, ObjectRef context,
+ String expression);
+}
diff --git a/runtime/observatory/lib/src/models/repositories/field.dart b/runtime/observatory/lib/src/models/repositories/field.dart
new file mode 100644
index 0000000..8412ac9
--- /dev/null
+++ b/runtime/observatory/lib/src/models/repositories/field.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+part of models;
+
+abstract class FieldRepository{
+ Future<Field> get(IsolateRef isolate, String id);
+}
diff --git a/runtime/observatory/lib/src/models/repositories/function.dart b/runtime/observatory/lib/src/models/repositories/function.dart
new file mode 100644
index 0000000..8ae36f3
--- /dev/null
+++ b/runtime/observatory/lib/src/models/repositories/function.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+part of models;
+
+abstract class FunctionRepository{
+ Future<Function> get(IsolateRef isolate, String id);
+}
diff --git a/runtime/observatory/lib/src/models/repositories/megamorphiccache.dart b/runtime/observatory/lib/src/models/repositories/megamorphiccache.dart
new file mode 100644
index 0000000..9734e3e
--- /dev/null
+++ b/runtime/observatory/lib/src/models/repositories/megamorphiccache.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+part of models;
+
+abstract class MegamorphicCacheRepository{
+ Future<MegamorphicCache> get(IsolateRef isolate, String id);
+}
diff --git a/runtime/observatory/lib/src/models/repositories/objectpool.dart b/runtime/observatory/lib/src/models/repositories/objectpool.dart
new file mode 100644
index 0000000..36f51ba
--- /dev/null
+++ b/runtime/observatory/lib/src/models/repositories/objectpool.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+part of models;
+
+abstract class ObjectPoolRepository {
+ Future<ObjectPool> get(IsolateRef isolate, String id);
+}
diff --git a/runtime/observatory/lib/src/models/repositories/objectstore.dart b/runtime/observatory/lib/src/models/repositories/objectstore.dart
new file mode 100644
index 0000000..ee1735c
--- /dev/null
+++ b/runtime/observatory/lib/src/models/repositories/objectstore.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+part of models;
+
+abstract class ObjectStoreRepository {
+ Future<ObjectStore> get(IsolateRef isolate);
+}
diff --git a/runtime/observatory/lib/src/models/repositories/persistent_handles.dart b/runtime/observatory/lib/src/models/repositories/persistent_handles.dart
new file mode 100644
index 0000000..62d6323
--- /dev/null
+++ b/runtime/observatory/lib/src/models/repositories/persistent_handles.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+part of models;
+
+abstract class PersistentHandlesRepository {
+ Future<PersistentHandles> get(IsolateRef isolate);
+}
diff --git a/runtime/observatory/lib/src/models/repositories/script.dart b/runtime/observatory/lib/src/models/repositories/script.dart
index 3073c2e..3ba2dc3 100644
--- a/runtime/observatory/lib/src/models/repositories/script.dart
+++ b/runtime/observatory/lib/src/models/repositories/script.dart
@@ -5,5 +5,5 @@
part of models;
abstract class ScriptRepository {
- Future<Script> get(String id);
+ Future<Script> get(IsolateRef isolate, String id);
}
diff --git a/runtime/observatory/lib/src/repositories/class.dart b/runtime/observatory/lib/src/repositories/class.dart
index 911c363..4d80729 100644
--- a/runtime/observatory/lib/src/repositories/class.dart
+++ b/runtime/observatory/lib/src/repositories/class.dart
@@ -5,14 +5,14 @@
part of repositories;
class ClassRepository extends M.ClassRepository {
- final S.Isolate isolate;
-
- ClassRepository(this.isolate);
-
- Future<M.Class> getObject() {
+ Future<M.Class> getObject(M.IsolateRef i) {
+ final isolate = i as S.Isolate;
+ assert(isolate != null);
return isolate.getClassHierarchy();
}
- Future<M.Class> get(String id) async {
+ Future<M.Class> get(M.IsolateRef i, String id) async {
+ final isolate = i as S.Isolate;
+ assert(isolate != null);
return (await isolate.getObject(id)) as S.Class;
}
}
diff --git a/runtime/observatory/lib/src/repositories/context.dart b/runtime/observatory/lib/src/repositories/context.dart
index a088428..5bb12e6 100644
--- a/runtime/observatory/lib/src/repositories/context.dart
+++ b/runtime/observatory/lib/src/repositories/context.dart
@@ -5,8 +5,6 @@
part of repositories;
class ContextRepository extends M.ContextRepository {
- ContextRepository();
-
Future<M.Context> get(M.IsolateRef i, String id) async{
S.Isolate isolate = i as S.Isolate;
assert(isolate != null);
diff --git a/runtime/observatory/lib/src/repositories/eval.dart b/runtime/observatory/lib/src/repositories/eval.dart
new file mode 100644
index 0000000..bf423ad
--- /dev/null
+++ b/runtime/observatory/lib/src/repositories/eval.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+part of repositories;
+
+class EvalRepository extends M.EvalRepository {
+ Future<M.ObjectRef> evaluate(M.IsolateRef i, M.ObjectRef o, String e) async {
+ S.Isolate isolate = i as S.Isolate;
+ S.ServiceObject object = o as S.HeapObject;
+ assert(isolate != null);
+ assert(object != null);
+ assert(e != null);
+ return (await isolate.eval(object, e)) as M.ObjectRef;
+ }
+}
diff --git a/runtime/observatory/lib/src/repositories/field.dart b/runtime/observatory/lib/src/repositories/field.dart
new file mode 100644
index 0000000..fce37d0
--- /dev/null
+++ b/runtime/observatory/lib/src/repositories/field.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+part of repositories;
+
+class FieldRepository extends M.FieldRepository {
+ Future<M.Field> get(M.IsolateRef i, String id) async{
+ S.Isolate isolate = i as S.Isolate;
+ assert(isolate != null);
+ return (await isolate.getObject(id)) as S.Field;
+ }
+}
diff --git a/runtime/observatory/lib/src/repositories/function.dart b/runtime/observatory/lib/src/repositories/function.dart
new file mode 100644
index 0000000..2ab1682
--- /dev/null
+++ b/runtime/observatory/lib/src/repositories/function.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+part of repositories;
+
+class FunctionRepository extends M.FunctionRepository {
+ Future<M.Function> get(M.IsolateRef i, String id) async{
+ S.Isolate isolate = i as S.Isolate;
+ assert(isolate != null);
+ return (await isolate.getObject(id)) as S.ServiceFunction;
+ }
+}
diff --git a/runtime/observatory/lib/src/repositories/icdata.dart b/runtime/observatory/lib/src/repositories/icdata.dart
index 18ce814..cf6165d 100644
--- a/runtime/observatory/lib/src/repositories/icdata.dart
+++ b/runtime/observatory/lib/src/repositories/icdata.dart
@@ -5,8 +5,6 @@
part of repositories;
class ICDataRepository extends M.ICDataRepository {
- ICDataRepository();
-
Future<M.ICData> get(M.IsolateRef i, String id) async{
S.Isolate isolate = i as S.Isolate;
assert(isolate != null);
diff --git a/runtime/observatory/lib/src/repositories/instance.dart b/runtime/observatory/lib/src/repositories/instance.dart
index 8f2b756..ad365d6 100644
--- a/runtime/observatory/lib/src/repositories/instance.dart
+++ b/runtime/observatory/lib/src/repositories/instance.dart
@@ -5,8 +5,6 @@
part of repositories;
class InstanceRepository extends M.InstanceRepository {
- InstanceRepository();
-
Future<M.Instance> get(M.IsolateRef i, String id,
{int count: S.kDefaultFieldLimit}) async{
S.Isolate isolate = i as S.Isolate;
diff --git a/runtime/observatory/lib/src/repositories/megamorphiccache.dart b/runtime/observatory/lib/src/repositories/megamorphiccache.dart
new file mode 100644
index 0000000..59adbe3
--- /dev/null
+++ b/runtime/observatory/lib/src/repositories/megamorphiccache.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+part of repositories;
+
+class MegamorphicCacheRepository extends M.MegamorphicCacheRepository {
+ Future<M.MegamorphicCache> get(M.IsolateRef i, String id) async{
+ S.Isolate isolate = i as S.Isolate;
+ assert(isolate != null);
+ return (await isolate.getObject(id)) as S.MegamorphicCache;
+ }
+}
diff --git a/runtime/observatory/lib/src/repositories/objectpool.dart b/runtime/observatory/lib/src/repositories/objectpool.dart
new file mode 100644
index 0000000..b10c9dc
--- /dev/null
+++ b/runtime/observatory/lib/src/repositories/objectpool.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+part of repositories;
+
+class ObjectPoolRepository extends M.ObjectPoolRepository {
+ Future<M.ObjectPool> get(M.IsolateRef i, String id) async{
+ S.Isolate isolate = i as S.Isolate;
+ assert(isolate != null);
+ return (await isolate.getObject(id)) as S.ObjectPool;
+ }
+}
diff --git a/runtime/observatory/lib/src/repositories/objectstore.dart b/runtime/observatory/lib/src/repositories/objectstore.dart
new file mode 100644
index 0000000..7456d9a
--- /dev/null
+++ b/runtime/observatory/lib/src/repositories/objectstore.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+part of repositories;
+
+class ObjectStoreRepository implements M.ObjectStoreRepository {
+ Future<M.ObjectStore> get(M.IsolateRef i) async {
+ S.Isolate isolate = i as S.Isolate;
+ assert(isolate != null);
+ return isolate.getObjectStore();
+ }
+}
diff --git a/runtime/observatory/lib/src/repositories/persistent_handles.dart b/runtime/observatory/lib/src/repositories/persistent_handles.dart
new file mode 100644
index 0000000..db94cbc
--- /dev/null
+++ b/runtime/observatory/lib/src/repositories/persistent_handles.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+part of repositories;
+
+class PersistentHandlesRepository implements M.PersistentHandlesRepository {
+ Future<M.PersistentHandles> get(M.IsolateRef i) async {
+ S.Isolate isolate = i as S.Isolate;
+ assert(isolate != null);
+ final response = await isolate.invokeRpc('_getPersistentHandles', {});
+ return new S.PersistentHandles(response);
+ }
+}
diff --git a/runtime/observatory/lib/src/repositories/reachable_size.dart b/runtime/observatory/lib/src/repositories/reachable_size.dart
index 945cd9f..e670942 100644
--- a/runtime/observatory/lib/src/repositories/reachable_size.dart
+++ b/runtime/observatory/lib/src/repositories/reachable_size.dart
@@ -5,7 +5,6 @@
part of repositories;
class ReachableSizeRepository implements M.ReachableSizeRepository {
-
Future<M.Guarded<M.Instance>> get(M.IsolateRef i, String id) async {
S.Isolate isolate = i as S.Isolate;
assert(isolate != null);
diff --git a/runtime/observatory/lib/src/repositories/retained_size.dart b/runtime/observatory/lib/src/repositories/retained_size.dart
index b81da34..3869254 100644
--- a/runtime/observatory/lib/src/repositories/retained_size.dart
+++ b/runtime/observatory/lib/src/repositories/retained_size.dart
@@ -5,7 +5,6 @@
part of repositories;
class RetainedSizeRepository implements M.RetainedSizeRepository {
-
Future<M.Guarded<M.Instance>> get(M.IsolateRef i, String id) async {
S.Isolate isolate = i as S.Isolate;
assert(isolate != null);
diff --git a/runtime/observatory/lib/src/repositories/retaining_path.dart b/runtime/observatory/lib/src/repositories/retaining_path.dart
index c658f91..1ff9835 100644
--- a/runtime/observatory/lib/src/repositories/retaining_path.dart
+++ b/runtime/observatory/lib/src/repositories/retaining_path.dart
@@ -5,7 +5,6 @@
part of repositories;
class RetainingPathRepository implements M.RetainingPathRepository {
-
Future<M.RetainingPath> get(M.IsolateRef i, String id) async {
S.Isolate isolate = i as S.Isolate;
assert(isolate != null);
diff --git a/runtime/observatory/lib/src/repositories/script.dart b/runtime/observatory/lib/src/repositories/script.dart
index 918de35..e0fea2d 100644
--- a/runtime/observatory/lib/src/repositories/script.dart
+++ b/runtime/observatory/lib/src/repositories/script.dart
@@ -5,11 +5,10 @@
part of repositories;
class ScriptRepository implements M.ScriptRepository {
- final S.Isolate isolate;
-
- ScriptRepository(this.isolate);
-
- Future<M.Script> get(String id) async {
+ Future<M.Script> get(M.IsolateRef i, String id) async {
+ S.Isolate isolate = i as S.Isolate;
+ assert(i != null);
+ assert(id != null);
return (await isolate.getObject(id)) as M.Script;
}
}
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index 0ebf02e..0d67dde 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -418,7 +418,7 @@
ServiceObject getFromMap(ObservableMap map);
}
-abstract class Location {
+abstract class Location implements M.Location {
Script get script;
int get tokenPos;
}
@@ -469,7 +469,9 @@
/// An [UnresolvedSourceLocation] represents a location in the source
// code which has not been precisely mapped to a token position.
-class UnresolvedSourceLocation extends ServiceObject implements Location {
+class UnresolvedSourceLocation extends ServiceObject
+ implements Location,
+ M.UnresolvedSourceLocation {
Script script;
String scriptUri;
int line;
@@ -1137,6 +1139,39 @@
handler = map['handler'];
}
+class PersistentHandles implements M.PersistentHandles {
+ final Iterable<PersistentHandle> elements;
+ final Iterable<WeakPersistentHandle> weakElements;
+
+ PersistentHandles(ServiceMap map)
+ : this.elements = map['persistentHandles']
+ .map((rmap) => new PersistentHandle(rmap)),
+ this.weakElements = map['weakPersistentHandles']
+ .map((rmap) => new WeakPersistentHandle(rmap));
+}
+
+class PersistentHandle implements M.PersistentHandle {
+ final HeapObject object;
+
+ PersistentHandle(ServiceMap map)
+ : object = map['object'];
+}
+
+class WeakPersistentHandle implements M.WeakPersistentHandle {
+ final int externalSize;
+ final String peer;
+ final String callbackSymbolName;
+ final String callbackAddress;
+ final HeapObject object;
+
+ WeakPersistentHandle(ServiceMap map)
+ : externalSize = int.parse(map['externalSize']),
+ peer = map['peer'],
+ callbackSymbolName = map['callbackSymbolName'],
+ callbackAddress = map['callbackAddress'],
+ object = map['object'];
+}
+
class HeapSpace extends Observable implements M.HeapSpace {
@observable int used = 0;
@observable int capacity = 0;
@@ -1710,7 +1745,7 @@
});
}
- Future<ServiceObject> _eval(ServiceObject target,
+ Future<ServiceObject> eval(ServiceObject target,
String expression) {
Map params = {
'targetId': target.id,
@@ -1819,14 +1854,14 @@
}
-class NamedField {
+class NamedField implements M.NamedField {
final String name;
- final ServiceObject value;
+ final M.ObjectRef value;
NamedField(this.name, this.value);
}
-class ObjectStore extends ServiceObject {
+class ObjectStore extends ServiceObject implements M.ObjectStore {
@observable List<NamedField> fields = new List<NamedField>();
ObjectStore._empty(ServiceObjectOwner owner) : super._empty(owner);
@@ -2209,7 +2244,7 @@
}
-class Library extends HeapObject implements M.LibraryRef {
+class Library extends HeapObject implements M.Library {
@observable String uri;
@reflectable final dependencies = new ObservableList<LibraryDependency>();
@reflectable final scripts = new ObservableList<Script>();
@@ -2261,7 +2296,7 @@
}
Future<ServiceObject> evaluate(String expression) {
- return isolate._eval(this, expression);
+ return isolate.eval(this, expression);
}
Script get rootScript {
@@ -2429,7 +2464,7 @@
}
Future<ServiceObject> evaluate(String expression) {
- return isolate._eval(this, expression);
+ return isolate.eval(this, expression);
}
Future<ServiceObject> setTraceAllocations(bool enable) {
@@ -2753,7 +2788,7 @@
}
Future<ServiceObject> evaluate(String expression) {
- return isolate._eval(this, expression);
+ return isolate.eval(this, expression);
}
String toString() => 'Instance($shortName)';
@@ -2944,7 +2979,7 @@
String toString() => 'Sentinel($kind)';
}
-class Field extends HeapObject implements M.FieldRef {
+class Field extends HeapObject implements M.Field {
// Library or Class.
@observable HeapObject dartOwner;
@observable Library library;
@@ -2957,7 +2992,8 @@
@observable String vmName;
@observable bool guardNullable;
- @observable var /* Class | String */ guardClass;
+ M.GuardClassKind guardClassKind;
+ @observable Class guardClass;
@observable String guardLength;
@observable SourceLocation location;
@@ -2990,7 +3026,21 @@
}
guardNullable = map['_guardNullable'];
- guardClass = map['_guardClass'];
+ if (map['_guardClass'] is Class) {
+ guardClass = map['_guardClass'];
+ guardClassKind = M.GuardClassKind.single;
+ } else {
+ switch (map['_guardClass']) {
+ case 'various':
+ guardClassKind = M.GuardClassKind.dynamic;
+ break;
+ case 'unknown':
+ default:
+ guardClassKind = M.GuardClassKind.unknown;
+ break;
+ }
+ }
+
guardLength = map['_guardLength'];
location = map['location'];
_loaded = true;
@@ -3574,11 +3624,11 @@
}
}
-class ObjectPool extends HeapObject implements M.ObjectPoolRef {
+class ObjectPool extends HeapObject implements M.ObjectPool {
bool get immutable => false;
@observable int length;
- @observable List entries;
+ @observable List<ObjectPoolEntry> entries;
ObjectPool._empty(ServiceObjectOwner owner) : super._empty(owner);
@@ -3590,10 +3640,47 @@
if (mapIsRef) {
return;
}
- entries = map['_entries'];
+ entries = map['_entries'].map((map) => new ObjectPoolEntry(map));
}
}
+class ObjectPoolEntry implements M.ObjectPoolEntry {
+ final int offset;
+ final M.ObjectPoolEntryKind kind;
+ final M.ObjectRef asObject;
+ final int asInteger;
+
+ factory ObjectPoolEntry(map) {
+ M.ObjectPoolEntryKind kind = stringToObjectPoolEntryKind(map['kind']);
+ int offset = map['offset'];
+ switch (kind) {
+ case M.ObjectPoolEntryKind.object:
+ return new ObjectPoolEntry._fromObject(map['value'], offset);
+ default:
+ return new ObjectPoolEntry._fromInteger(kind, map['value'], offset);
+ }
+ }
+
+ ObjectPoolEntry._fromObject(this.asObject, this.offset)
+ : kind = M.ObjectPoolEntryKind.object,
+ asInteger = null;
+
+ ObjectPoolEntry._fromInteger(this.kind, this.asInteger, this.offset)
+ : asObject = null;
+}
+
+M.ObjectPoolEntryKind stringToObjectPoolEntryKind(String kind) {
+ switch (kind) {
+ case 'Object':
+ return M.ObjectPoolEntryKind.object;
+ case 'Immediate':
+ return M.ObjectPoolEntryKind.immediate;
+ case 'NativeEntry':
+ return M.ObjectPoolEntryKind.nativeEntry;
+ }
+ throw new Exception('Unknown ObjectPoolEntryKind ($kind)');
+}
+
class ICData extends HeapObject implements M.ICData {
@observable HeapObject dartOwner;
@observable String selector;
@@ -3618,7 +3705,7 @@
}
}
-class MegamorphicCache extends HeapObject implements M.MegamorphicCacheRef {
+class MegamorphicCache extends HeapObject implements M.MegamorphicCache {
@observable int mask;
@observable Instance buckets;
@observable String selector;
diff --git a/runtime/observatory/observatory_sources.gypi b/runtime/observatory/observatory_sources.gypi
index 89113b9..982025a 100644
--- a/runtime/observatory/observatory_sources.gypi
+++ b/runtime/observatory/observatory_sources.gypi
@@ -63,23 +63,19 @@
'lib/src/elements/error_ref.dart',
'lib/src/elements/error_ref_wrapper.dart',
'lib/src/elements/error_view.dart',
- 'lib/src/elements/error_view.html',
'lib/src/elements/eval_box.dart',
- 'lib/src/elements/eval_box.html',
+ 'lib/src/elements/eval_box_wrapper.dart',
'lib/src/elements/eval_link.dart',
'lib/src/elements/eval_link.html',
'lib/src/elements/field_ref.dart',
'lib/src/elements/field_ref_wrapper.dart',
'lib/src/elements/field_view.dart',
- 'lib/src/elements/field_view.html',
'lib/src/elements/flag_list.dart',
'lib/src/elements/function_ref.dart',
'lib/src/elements/function_ref_wrapper.dart',
'lib/src/elements/function_view.dart',
- 'lib/src/elements/function_view.html',
'lib/src/elements/general_error.dart',
'lib/src/elements/heap_map.dart',
- 'lib/src/elements/heap_map.html',
'lib/src/elements/heap_snapshot.dart',
'lib/src/elements/helpers/any_ref.dart',
'lib/src/elements/helpers/rendering_queue.dart',
@@ -119,7 +115,6 @@
'lib/src/elements/logging.html',
'lib/src/elements/megamorphiccache_ref.dart',
'lib/src/elements/megamorphiccache_view.dart',
- 'lib/src/elements/megamorphiccache_view.html',
'lib/src/elements/metrics.dart',
'lib/src/elements/metrics.html',
'lib/src/elements/nav/bar.dart',
@@ -149,29 +144,27 @@
'lib/src/elements/object_view.html',
'lib/src/elements/objectpool_ref.dart',
'lib/src/elements/objectpool_view.dart',
- 'lib/src/elements/objectpool_view.html',
'lib/src/elements/objectstore_view.dart',
- 'lib/src/elements/objectstore_view.html',
'lib/src/elements/observatory_application.dart',
'lib/src/elements/observatory_element.dart',
'lib/src/elements/pc_descriptors_ref.dart',
'lib/src/elements/persistent_handles.dart',
- 'lib/src/elements/persistent_handles.html',
'lib/src/elements/ports.dart',
'lib/src/elements/retaining_path.dart',
'lib/src/elements/sample_buffer_control.dart',
'lib/src/elements/script_inset.dart',
- 'lib/src/elements/script_inset.html',
+ 'lib/src/elements/script_inset_wrapper.dart',
'lib/src/elements/script_ref.dart',
'lib/src/elements/script_ref_wrapper.dart',
'lib/src/elements/script_view.dart',
- 'lib/src/elements/script_view.html',
'lib/src/elements/sentinel_value.dart',
'lib/src/elements/service_ref.dart',
'lib/src/elements/service_ref.html',
'lib/src/elements/service_view.dart',
'lib/src/elements/service_view.html',
'lib/src/elements/shims/binding.dart',
+ 'lib/src/elements/source_inset.dart',
+ 'lib/src/elements/source_inset_wrapper.dart',
'lib/src/elements/source_link.dart',
'lib/src/elements/source_link_wrapper.dart',
'lib/src/elements/stack_trace_tree_config.dart',
@@ -213,7 +206,9 @@
'lib/src/models/objects/notification.dart',
'lib/src/models/objects/object.dart',
'lib/src/models/objects/objectpool.dart',
+ 'lib/src/models/objects/objectstore.dart',
'lib/src/models/objects/pc_descriptors.dart',
+ 'lib/src/models/objects/persistent_handles.dart',
'lib/src/models/objects/ports.dart',
'lib/src/models/objects/retaining_path.dart',
'lib/src/models/objects/sample_profile.dart',
@@ -228,13 +223,20 @@
'lib/src/models/repositories/allocation_profile.dart',
'lib/src/models/repositories/class.dart',
'lib/src/models/repositories/context.dart',
+ 'lib/src/models/repositories/eval.dart',
'lib/src/models/repositories/event.dart',
+ 'lib/src/models/repositories/field.dart',
'lib/src/models/repositories/flag.dart',
+ 'lib/src/models/repositories/function.dart',
'lib/src/models/repositories/heap_snapshot.dart',
'lib/src/models/repositories/icdata.dart',
'lib/src/models/repositories/inbound_references.dart',
'lib/src/models/repositories/instance.dart',
+ 'lib/src/models/repositories/megamorphiccache.dart',
'lib/src/models/repositories/notification.dart',
+ 'lib/src/models/repositories/objectpool.dart',
+ 'lib/src/models/repositories/objectstore.dart',
+ 'lib/src/models/repositories/persistent_handles.dart',
'lib/src/models/repositories/ports.dart',
'lib/src/models/repositories/reachable_size.dart',
'lib/src/models/repositories/retained_size.dart',
@@ -245,13 +247,20 @@
'lib/src/repositories/allocation_profile.dart',
'lib/src/repositories/class.dart',
'lib/src/repositories/context.dart',
+ 'lib/src/repositories/eval.dart',
'lib/src/repositories/event.dart',
+ 'lib/src/repositories/field.dart',
'lib/src/repositories/flag.dart',
+ 'lib/src/repositories/function.dart',
'lib/src/repositories/heap_snapshot.dart',
'lib/src/repositories/icdata.dart',
'lib/src/repositories/inbound_references.dart',
'lib/src/repositories/instance.dart',
+ 'lib/src/repositories/megamorphiccache.dart',
'lib/src/repositories/notification.dart',
+ 'lib/src/repositories/objectpool.dart',
+ 'lib/src/repositories/objectstore.dart',
+ 'lib/src/repositories/persistent_handles.dart',
'lib/src/repositories/ports.dart',
'lib/src/repositories/reachable_size.dart',
'lib/src/repositories/retained_size.dart',
diff --git a/runtime/observatory/tests/observatory_ui/class_tree/element_test.dart b/runtime/observatory/tests/observatory_ui/class_tree/element_test.dart
index 5d20331..f8c9785 100644
--- a/runtime/observatory/tests/observatory_ui/class_tree/element_test.dart
+++ b/runtime/observatory/tests/observatory_ui/class_tree/element_test.dart
@@ -39,11 +39,13 @@
bool rendered = false;
final e = new ClassTreeElement(vm, isolate, events, notifications,
new ClassRepositoryMock(
- object: expectAsync(() async {
+ object: expectAsync((i) async {
+ expect(i, equals(isolate));
expect(rendered, isFalse);
return object;
}, count: 1),
- getter: expectAsync((id) async {
+ getter: expectAsync((i, id) async {
+ expect(i, equals(isolate));
expect(ids.contains(id), isTrue);
switch (id) {
case child1_id: return child1;
diff --git a/runtime/observatory/tests/observatory_ui/error_view/element_test.dart b/runtime/observatory/tests/observatory_ui/error_view/element_test.dart
new file mode 100644
index 0000000..7d30a03
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/error_view/element_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/error_view.dart';
+import '../mocks.dart';
+
+main() {
+ ErrorViewElement.tag.ensureRegistration();
+
+ final notifs = new NotificationRepositoryMock();
+ final error = const ErrorMock();
+ test('instantiation', () {
+ final e = new ErrorViewElement(notifs, error);
+ expect(e, isNotNull, reason: 'element correctly created');
+ expect(e.error, equals(error));
+ });
+ test('elements created after attachment', () async {
+ final e = new ErrorViewElement(notifs, error);
+ document.body.append(e);
+ await e.onRendered.first;
+ expect(e.children.length, isNonZero, reason: 'has elements');
+ e.remove();
+ await e.onRendered.first;
+ expect(e.children.length, isZero, reason: 'is empty');
+ });
+}
diff --git a/runtime/observatory/tests/observatory_ui/error_view/element_test.html b/runtime/observatory/tests/observatory_ui/error_view/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/error_view/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <meta name="dart.unittest" content="full-stack-traces">
+ <style>
+ .unittest-table { font-family:monospace; border:1px; }
+ .unittest-pass { background: #6b3;}
+ .unittest-fail { background: #d55;}
+ .unittest-error { background: #a11;}
+ </style>
+ <script src="/packages/web_components/webcomponents.js"></script>
+ <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+ <script type="text/javascript"
+ src="/root_dart/tools/testing/dart/test_controller.js"></script>
+ %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/megamorphiccache_view/element_test.dart b/runtime/observatory/tests/observatory_ui/megamorphiccache_view/element_test.dart
new file mode 100644
index 0000000..06f3d65
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/megamorphiccache_view/element_test.dart
@@ -0,0 +1,60 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/megamorphiccache_view.dart';
+import 'package:observatory/src/elements/nav/refresh.dart';
+import 'package:observatory/src/elements/object_common.dart';
+import '../mocks.dart';
+
+main() {
+ MegamorphicCacheViewElement.tag.ensureRegistration();
+
+ final cTag = ObjectCommonElement.tag.name;
+ final rTag = NavRefreshElement.tag.name;
+
+ const vm = const VMMock();
+ const isolate = const IsolateRefMock();
+ final events = new EventRepositoryMock();
+ final notifs = new NotificationRepositoryMock();
+ final cache = const MegamorphicCacheMock();
+ final caches = new MegamorphicCacheRepositoryMock();
+ final reachableSizes = new ReachableSizeRepositoryMock();
+ final retainedSizes = new RetainedSizeRepositoryMock();
+ final inbounds = new InboundReferencesRepositoryMock();
+ final paths = new RetainingPathRepositoryMock();
+ final instances = new InstanceRepositoryMock();
+ test('instantiation', () {
+ final e = new MegamorphicCacheViewElement(vm, isolate, cache, events,
+ notifs, caches, retainedSizes,
+ reachableSizes, inbounds, paths,
+ instances);
+ expect(e, isNotNull, reason: 'element correctly created');
+ expect(e.isolate, equals(isolate));
+ expect(e.cache, equals(cache));
+ });
+ test('elements created after attachment', () async {
+ final caches = new MegamorphicCacheRepositoryMock(
+ getter: expectAsync((i, id) async {
+ expect(i, equals(isolate));
+ expect(id, equals(cache.id));
+ return cache;
+ }, count: 1)
+ );
+ final e = new MegamorphicCacheViewElement(vm, isolate, cache, events,
+ notifs, caches, retainedSizes,
+ reachableSizes, inbounds, paths,
+ instances);
+ document.body.append(e);
+ await e.onRendered.first;
+ expect(e.children.length, isNonZero, reason: 'has elements');
+ expect(e.querySelectorAll(cTag).length, equals(1));
+ (e.querySelector(rTag) as NavRefreshElement).refresh();
+ await e.onRendered.first;
+ e.remove();
+ await e.onRendered.first;
+ expect(e.children.length, isZero, reason: 'is empty');
+ });
+}
diff --git a/runtime/observatory/tests/observatory_ui/megamorphiccache_view/element_test.html b/runtime/observatory/tests/observatory_ui/megamorphiccache_view/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/megamorphiccache_view/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <meta name="dart.unittest" content="full-stack-traces">
+ <style>
+ .unittest-table { font-family:monospace; border:1px; }
+ .unittest-pass { background: #6b3;}
+ .unittest-fail { background: #d55;}
+ .unittest-error { background: #a11;}
+ </style>
+ <script src="/packages/web_components/webcomponents.js"></script>
+ <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+ <script type="text/javascript"
+ src="/root_dart/tools/testing/dart/test_controller.js"></script>
+ %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/mocks.dart b/runtime/observatory/tests/observatory_ui/mocks.dart
index 28bc264..f7f2b82 100644
--- a/runtime/observatory/tests/observatory_ui/mocks.dart
+++ b/runtime/observatory/tests/observatory_ui/mocks.dart
@@ -31,7 +31,9 @@
part 'mocks/objects/megamorphiccache.dart';
part 'mocks/objects/notification.dart';
part 'mocks/objects/objectpool.dart';
+part 'mocks/objects/objectstore.dart';
part 'mocks/objects/pc_descriptors.dart';
+part 'mocks/objects/persistent_handles.dart';
part 'mocks/objects/ports.dart';
part 'mocks/objects/retaining_path.dart';
part 'mocks/objects/sample_profile.dart';
@@ -52,8 +54,12 @@
part 'mocks/repositories/icdata.dart';
part 'mocks/repositories/inbound_references.dart';
part 'mocks/repositories/instance.dart';
+part 'mocks/repositories/megamorphiccache.dart';
part 'mocks/repositories/notification.dart';
+part 'mocks/repositories/objectpool.dart';
+part 'mocks/repositories/objectstore.dart';
part 'mocks/repositories/ports.dart';
+part 'mocks/repositories/persistent_handles.dart';
part 'mocks/repositories/reachable_size.dart';
part 'mocks/repositories/retained_size.dart';
part 'mocks/repositories/retaining_path.dart';
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/error.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/error.dart
index 1a87016..f3a4798 100644
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/error.dart
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/error.dart
@@ -8,7 +8,10 @@
final String id;
final M.ErrorKind kind;
final String message;
- const ErrorRefMock({this.id, this.kind, this.message});
+
+ const ErrorRefMock({this.id: 'error-ref',
+ this.kind: M.ErrorKind.internalError,
+ this.message: 'Error Message'});
}
class ErrorMock implements M.Error {
@@ -17,5 +20,8 @@
final int size;
final M.ErrorKind kind;
final String message;
- const ErrorMock({this.id, this.clazz, this.size, this.kind, this.message});
+
+ const ErrorMock({this.id: 'error-id', this.clazz: const ClassMock(),
+ this.size: 0, this.kind: M.ErrorKind.internalError,
+ this.message: 'Error Message'});
}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/function.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/function.dart
index 85eae71..d017211 100644
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/function.dart
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/function.dart
@@ -27,7 +27,22 @@
final M.FunctionKind kind;
final M.SourceLocation location;
final M.CodeRef code;
+ final M.CodeRef unoptimizedCode;
+ final M.FieldRef field;
+ final int usageCounter;
+ final M.InstanceRef icDataArray;
+ final int deoptimizations;
+ final bool isOptimizable;
+ final bool isInlinable;
+ final bool hasIntrinsic;
+ final bool isRecognized;
+ final bool isNative;
+ final String vmName;
const FunctionMock({this.id, this.name, this.clazz, this.size, this.dartOwner,
this.isStatic : false, this.isConst : false, this.kind, this.location,
- this.code});
+ this.code, this.unoptimizedCode, this.field, this.usageCounter: 0,
+ this.icDataArray: const InstanceRefMock(), this.deoptimizations: 0,
+ this.isOptimizable: false, this.isInlinable: false,
+ this.hasIntrinsic: false, this.isRecognized: false, this.isNative: false,
+ this.vmName: 'function-vm-name',});
}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/megamorphiccache.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/megamorphiccache.dart
index 6e58941..07da7f1 100644
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/megamorphiccache.dart
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/megamorphiccache.dart
@@ -9,5 +9,20 @@
final String selector;
const MegamorphicCacheRefMock({this.id : 'megamorphiccache-id',
- this.selector});
+ this.selector: 'selector'});
+}
+
+class MegamorphicCacheMock implements M.MegamorphicCache {
+ final String id;
+ final M.ClassRef clazz;
+ final int size;
+ final String selector;
+ final int mask;
+ final M.InstanceRef buckets;
+ final M.InstanceRef argumentsDescriptor;
+
+ const MegamorphicCacheMock({this.id : 'megamorphiccache-id',
+ this.clazz: const ClassRefMock(), this.size: 1, this.selector: 'selector',
+ this.mask: 0, this.buckets: const InstanceRefMock(),
+ this.argumentsDescriptor: const InstanceRefMock()});
}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/objectpool.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/objectpool.dart
index 59932ee..0124fcd 100644
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/objectpool.dart
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/objectpool.dart
@@ -10,3 +10,27 @@
const ObjectPoolRefMock({this.id: 'objectpool-id', this.length: 0});
}
+
+class ObjectPoolMock implements M.ObjectPool {
+ final String id;
+ final M.ClassRef clazz;
+ final int size;
+ final int length;
+ final Iterable<M.ObjectPoolEntry> entries;
+
+ const ObjectPoolMock({this.id: 'objectpool-id',
+ this.clazz: const ClassRefMock(), this.size: 1,
+ this.length: 0, this.entries: const []});
+}
+
+class ObjectPoolEntryMock implements M.ObjectPoolEntry {
+ final int offset;
+ final M.ObjectPoolEntryKind kind;
+ final M.ObjectRef asObject;
+ final int asInteger;
+
+ const ObjectPoolEntryMock({this.offset: 0,
+ this.kind: M.ObjectPoolEntryKind.object,
+ this.asObject: const InstanceRefMock(),
+ this.asInteger: null});
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/objectstore.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/objectstore.dart
new file mode 100644
index 0000000..ee1216c
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/objectstore.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of mocks;
+
+class ObjectStoreMock implements M.ObjectStore {
+ final Iterable<M.NamedField> fields;
+
+ const ObjectStoreMock({this.fields: const []});
+}
+
+class NamedFieldMock implements M.NamedField {
+ final String name;
+ final M.ObjectRef value;
+
+ const NamedFieldMock({this.name: 'field-name',
+ this.value: const InstanceRefMock()});
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/persistent_handles.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/persistent_handles.dart
new file mode 100644
index 0000000..5e65785
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/persistent_handles.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of mocks;
+
+class PersistentHandlesMock implements M.PersistentHandles {
+ final Iterable<M.PersistentHandle> elements;
+ final Iterable<M.WeakPersistentHandle> weakElements;
+
+ const PersistentHandlesMock({this.elements: const [],
+ this.weakElements: const []});
+}
+
+class PersistentHandleMock implements M.PersistentHandle {
+ final M.ObjectRef object;
+
+ const PersistentHandleMock({this.object: const InstanceRefMock()});
+}
+
+class WeakPersistentHandleMock implements M.WeakPersistentHandle {
+ final M.ObjectRef object;
+ final int externalSize;
+ final String peer;
+ final String callbackSymbolName;
+ final String callbackAddress;
+
+ const WeakPersistentHandleMock({this.object: const InstanceRefMock(),
+ this.externalSize: 0, this.peer: '0x0',
+ this.callbackSymbolName: 'dart::Something()',
+ this.callbackAddress: '0x123456'});
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/script.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/script.dart
index c5139bc..86e139f 100644
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/script.dart
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/script.dart
@@ -19,15 +19,24 @@
final int size;
final String uri;
final String source;
+ final M.LibraryRef library;
final TokenToInt _tokenToLine;
final TokenToInt _tokenToCol;
+ final DateTime loadTime;
+ final int firstTokenPos;
+ final int lastTokenPos;
+ final int lineOffset;
+ final int columnOffset;
+
int tokenToLine(int token) => _tokenToLine(token);
int tokenToCol(int token) => _tokenToCol(token);
const ScriptMock({this.id, this.clazz, this.size, this.uri, this.source,
- TokenToInt tokenToLine, TokenToInt tokenToCol})
+ this.library: const LibraryRefMock(), TokenToInt tokenToLine,
+ TokenToInt tokenToCol, this.loadTime, this.firstTokenPos,
+ this.lastTokenPos, this.lineOffset, this.columnOffset})
: _tokenToLine = tokenToLine,
_tokenToCol = tokenToCol;
}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/class.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/class.dart
index 3c5fe7b..debb14c 100644
--- a/runtime/observatory/tests/observatory_ui/mocks/repositories/class.dart
+++ b/runtime/observatory/tests/observatory_ui/mocks/repositories/class.dart
@@ -4,8 +4,9 @@
part of mocks;
-typedef Future<M.Class> ClassRepositoryMockObjectCallback();
-typedef Future<M.Class> ClassRepositoryMockGetterCallback(String id);
+typedef Future<M.Class> ClassRepositoryMockObjectCallback(M.Isolate isolate);
+typedef Future<M.Class>
+ ClassRepositoryMockGetterCallback(M.Isolate isolate, String id);
class ClassRepositoryMock implements M.ClassRepository {
final ClassRepositoryMockObjectCallback _object;
@@ -16,16 +17,16 @@
: _object = object,
_get = getter;
- Future<M.Class> getObject(){
+ Future<M.Class> getObject(M.IsolateRef i){
if (_object != null) {
- return _object();
+ return _object(i);
}
return new Future.value(null);
}
- Future<M.Class> get(String id){
+ Future<M.Class> get(M.IsolateRef i, String id){
if (_get != null) {
- return _get(id);
+ return _get(i, id);
}
return new Future.value(null);
}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/megamorphiccache.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/megamorphiccache.dart
new file mode 100644
index 0000000..340bad3
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/repositories/megamorphiccache.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of mocks;
+
+typedef Future<M.MegamorphicCache>
+ MegamorphicCacheRepositoryMockCallback(M.IsolateRef isolate, String id);
+
+class MegamorphicCacheRepositoryMock implements M.MegamorphicCacheRepository {
+ final MegamorphicCacheRepositoryMockCallback _get;
+
+ MegamorphicCacheRepositoryMock(
+ {MegamorphicCacheRepositoryMockCallback getter})
+ : _get = getter;
+
+ Future<M.MegamorphicCache> get(M.IsolateRef isolate, String id, {int count}){
+ if (_get != null) {
+ return _get(isolate, id);
+ }
+ return new Future.value(null);
+ }
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/objectpool.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/objectpool.dart
new file mode 100644
index 0000000..b3b139c
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/repositories/objectpool.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+part of mocks;
+
+typedef Future<M.ObjectPool>
+ ObjectPoolRepositoryMockGetter(M.IsolateRef i, String id);
+
+class ObjectPoolRepositoryMock implements M.ObjectPoolRepository {
+ final ObjectPoolRepositoryMockGetter _getter;
+
+ Future<M.ObjectPool> get(M.IsolateRef i, String id) {
+ if (_getter != null) {
+ return _getter(i, id);
+ }
+ return new Future.value(new ObjectPoolMock());
+ }
+
+ ObjectPoolRepositoryMock({ObjectPoolRepositoryMockGetter getter})
+ : _getter = getter;
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/objectstore.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/objectstore.dart
new file mode 100644
index 0000000..02bd9b4
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/repositories/objectstore.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+part of mocks;
+
+typedef Future<M.ObjectStore> ObjectStoreRepositoryMockGetter(M.IsolateRef i);
+
+class ObjectStoreRepositoryMock implements M.ObjectStoreRepository {
+ final ObjectStoreRepositoryMockGetter _getter;
+
+ Future<M.ObjectStore> get(M.IsolateRef i) {
+ if (_getter != null) {
+ return _getter(i);
+ }
+ return new Future.value(new ObjectStoreMock());
+ }
+
+ ObjectStoreRepositoryMock({ObjectStoreRepositoryMockGetter getter})
+ : _getter = getter;
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/persistent_handles.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/persistent_handles.dart
new file mode 100644
index 0000000..713be46
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/repositories/persistent_handles.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+part of mocks;
+
+typedef Future<M.PersistentHandles>
+ PersistentHandlesRepositoryMockGetter(M.IsolateRef i);
+
+class PersistentHandlesRepositoryMock implements M.PersistentHandlesRepository {
+ final PersistentHandlesRepositoryMockGetter _getter;
+
+ Future<M.PersistentHandles> get(M.IsolateRef i) {
+ if (_getter != null) {
+ return _getter(i);
+ }
+ return new Future.value(new PortsMock());
+ }
+
+ PersistentHandlesRepositoryMock(
+ {PersistentHandlesRepositoryMockGetter getter})
+ : _getter = getter;
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/script.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/script.dart
index 78b9610..cb6d2eb 100644
--- a/runtime/observatory/tests/observatory_ui/mocks/repositories/script.dart
+++ b/runtime/observatory/tests/observatory_ui/mocks/repositories/script.dart
@@ -4,7 +4,8 @@
part of mocks;
-typedef Future<M.Script> ScriptRepositoryMockCallback(String id);
+typedef Future<M.Script>
+ ScriptRepositoryMockCallback(M.IsolateRef isolate, String id);
class ScriptRepositoryMock implements M.ScriptRepository {
final ScriptRepositoryMockCallback _get;
@@ -12,9 +13,9 @@
ScriptRepositoryMock({ScriptRepositoryMockCallback getter})
: _get = getter;
- Future<M.Script> get(String id){
+ Future<M.Script> get(M.IsolateRef isolate, String id){
if (_get != null) {
- return _get(id);
+ return _get(isolate, id);
}
return new Future.value(null);
}
diff --git a/runtime/observatory/tests/observatory_ui/objectpool_view/element_test.dart b/runtime/observatory/tests/observatory_ui/objectpool_view/element_test.dart
new file mode 100644
index 0000000..11f2ee9
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/objectpool_view/element_test.dart
@@ -0,0 +1,58 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/nav/refresh.dart';
+import 'package:observatory/src/elements/object_common.dart';
+import 'package:observatory/src/elements/objectpool_view.dart';
+import '../mocks.dart';
+
+main() {
+ ObjectPoolViewElement.tag.ensureRegistration();
+
+ final cTag = ObjectCommonElement.tag.name;
+ final rTag = NavRefreshElement.tag.name;
+
+ const vm = const VMMock();
+ const isolate = const IsolateRefMock();
+ final events = new EventRepositoryMock();
+ final notifs = new NotificationRepositoryMock();
+ final pool = const ObjectPoolMock();
+ final pools = new ObjectPoolRepositoryMock();
+ final reachableSizes = new ReachableSizeRepositoryMock();
+ final retainedSizes = new RetainedSizeRepositoryMock();
+ final inbounds = new InboundReferencesRepositoryMock();
+ final paths = new RetainingPathRepositoryMock();
+ final instances = new InstanceRepositoryMock();
+ test('instantiation', () {
+ final e = new ObjectPoolViewElement(vm, isolate, pool, events, notifs,
+ pools, retainedSizes, reachableSizes,
+ inbounds, paths, instances);
+ expect(e, isNotNull, reason: 'element correctly created');
+ expect(e.isolate, equals(isolate));
+ expect(e.pool, equals(pool));
+ });
+ test('elements created after attachment', () async {
+ final pools = new ObjectPoolRepositoryMock(
+ getter: expectAsync((i, id) async {
+ expect(i, equals(isolate));
+ expect(id, equals(pool.id));
+ return pool;
+ }, count: 1)
+ );
+ final e = new ObjectPoolViewElement(vm, isolate, pool, events, notifs,
+ pools, retainedSizes, reachableSizes,
+ inbounds, paths, instances);
+ document.body.append(e);
+ await e.onRendered.first;
+ expect(e.children.length, isNonZero, reason: 'has elements');
+ expect(e.querySelectorAll(cTag).length, equals(1));
+ (e.querySelector(rTag) as NavRefreshElement).refresh();
+ await e.onRendered.first;
+ e.remove();
+ await e.onRendered.first;
+ expect(e.children.length, isZero, reason: 'is empty');
+ });
+}
diff --git a/runtime/observatory/tests/observatory_ui/objectpool_view/element_test.html b/runtime/observatory/tests/observatory_ui/objectpool_view/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/objectpool_view/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <meta name="dart.unittest" content="full-stack-traces">
+ <style>
+ .unittest-table { font-family:monospace; border:1px; }
+ .unittest-pass { background: #6b3;}
+ .unittest-fail { background: #d55;}
+ .unittest-error { background: #a11;}
+ </style>
+ <script src="/packages/web_components/webcomponents.js"></script>
+ <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+ <script type="text/javascript"
+ src="/root_dart/tools/testing/dart/test_controller.js"></script>
+ %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/objectstore_view/element_test.dart b/runtime/observatory/tests/observatory_ui/objectstore_view/element_test.dart
new file mode 100644
index 0000000..1889b49
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/objectstore_view/element_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/objectstore_view.dart';
+import '../mocks.dart';
+
+main() {
+ ObjectStoreViewElement.tag.ensureRegistration();
+
+ const vm = const VMMock();
+ const isolate = const IsolateRefMock();
+ final events = new EventRepositoryMock();
+ final notifs = new NotificationRepositoryMock();
+ final stores = new ObjectStoreRepositoryMock();
+ final instances = new InstanceRepositoryMock();
+ test('instantiation', () {
+ final e = new ObjectStoreViewElement(vm, isolate, events, notifs, stores, instances);
+ expect(e, isNotNull, reason: 'element correctly created');
+ expect(e.isolate, equals(isolate));
+ });
+ test('elements created after attachment', () async {
+ const fields = const [
+ const NamedFieldMock(name: 'field-1'),
+ const NamedFieldMock(name: 'field-2'),
+ const NamedFieldMock(name: 'field-3')
+ ];
+ const store = const ObjectStoreMock(fields: fields);
+ final stores = new ObjectStoreRepositoryMock(
+ getter: expectAsync((i) async {
+ expect(i, equals(isolate));
+ return store;
+ }, count: 1)
+ );
+ final instances = new InstanceRepositoryMock();
+ final e = new ObjectStoreViewElement(vm, isolate, events, notifs, stores, instances);
+ document.body.append(e);
+ await e.onRendered.first;
+ expect(e.children.length, isNonZero, reason: 'has elements');
+ expect(e.querySelectorAll('.memberItem').length, equals(fields.length));
+ e.remove();
+ await e.onRendered.first;
+ expect(e.children.length, isZero, reason: 'is empty');
+ });
+}
diff --git a/runtime/observatory/tests/observatory_ui/objectstore_view/element_test.html b/runtime/observatory/tests/observatory_ui/objectstore_view/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/objectstore_view/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <meta name="dart.unittest" content="full-stack-traces">
+ <style>
+ .unittest-table { font-family:monospace; border:1px; }
+ .unittest-pass { background: #6b3;}
+ .unittest-fail { background: #d55;}
+ .unittest-error { background: #a11;}
+ </style>
+ <script src="/packages/web_components/webcomponents.js"></script>
+ <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+ <script type="text/javascript"
+ src="/root_dart/tools/testing/dart/test_controller.js"></script>
+ %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/observatory_ui.status b/runtime/observatory/tests/observatory_ui/observatory_ui.status
index e307635..f683fd8 100644
--- a/runtime/observatory/tests/observatory_ui/observatory_ui.status
+++ b/runtime/observatory/tests/observatory_ui/observatory_ui.status
@@ -2,7 +2,7 @@
# 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.
-[ $browser == false || $runtime == drt ]
+[ $browser == false || $runtime == drt || $fast_startup]
*: SkipByDesign
[ $runtime == dartium ]
@@ -12,3 +12,4 @@
[ $runtime == ff || $runtime == safari ]
allocation_profile: Skip
cpu_profile_table: Skip
+persistent_handles_page: Skip
diff --git a/runtime/observatory/tests/observatory_ui/persistent_handles_page/element_test.dart b/runtime/observatory/tests/observatory_ui/persistent_handles_page/element_test.dart
new file mode 100644
index 0000000..f2e4b84
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/persistent_handles_page/element_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/persistent_handles.dart';
+import '../mocks.dart';
+
+main() {
+ PersistentHandlesPageElement.tag.ensureRegistration();
+
+ const vm = const VMMock();
+ const isolate = const IsolateRefMock();
+ final events = new EventRepositoryMock();
+ final notifs = new NotificationRepositoryMock();
+ final repository = new PersistentHandlesRepositoryMock();
+ final instances = new InstanceRepositoryMock();
+ test('instantiation', () {
+ final e = new PersistentHandlesPageElement(vm, isolate, events, notifs,
+ repository, instances);
+ expect(e, isNotNull, reason: 'element correctly created');
+ expect(e.isolate, equals(isolate));
+ });
+ test('elements created after attachment', () async {
+ final repository = new PersistentHandlesRepositoryMock(
+ getter: expectAsync((i) async {
+ expect(i, equals(isolate));
+ return const PersistentHandlesMock();
+ }, count: 1)
+ );
+ final instances = new InstanceRepositoryMock();
+ final e = new PersistentHandlesPageElement(vm, isolate, events, notifs,
+ repository, instances);
+ document.body.append(e);
+ await e.onRendered.first;
+ expect(e.children.length, isNonZero, reason: 'has elements');
+ e.remove();
+ await e.onRendered.first;
+ expect(e.children.length, isZero, reason: 'is empty');
+ });
+}
diff --git a/runtime/observatory/tests/observatory_ui/persistent_handles_page/element_test.html b/runtime/observatory/tests/observatory_ui/persistent_handles_page/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/persistent_handles_page/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <meta name="dart.unittest" content="full-stack-traces">
+ <style>
+ .unittest-table { font-family:monospace; border:1px; }
+ .unittest-pass { background: #6b3;}
+ .unittest-fail { background: #d55;}
+ .unittest-error { background: #a11;}
+ </style>
+ <script src="/packages/web_components/webcomponents.js"></script>
+ <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+ <script type="text/javascript"
+ src="/root_dart/tools/testing/dart/test_controller.js"></script>
+ %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/source_link/element_test.dart b/runtime/observatory/tests/observatory_ui/source_link/element_test.dart
index bd096b8..38218f3 100644
--- a/runtime/observatory/tests/observatory_ui/source_link/element_test.dart
+++ b/runtime/observatory/tests/observatory_ui/source_link/element_test.dart
@@ -17,21 +17,23 @@
tokenToLine: (int token) => 1, tokenToCol: (int token) => 2);
final location = new SourceLocationMock(script: script, tokenPos: 0,
endTokenPos: 1);
+ final repository = new ScriptRepositoryMock();
test('instantiation', () {
- final e = new SourceLinkElement(isolate, location,
- new ScriptRepositoryMock());
+ final e = new SourceLinkElement(isolate, location, repository);
expect(e, isNotNull, reason: 'element correctly created');
expect(e.isolate, equals(isolate));
expect(e.location, equals(location));
});
test('elements created after attachment', () async {
bool rendered = false;
- final e = new SourceLinkElement(isolate, location,
- new ScriptRepositoryMock(getter: expectAsync((String id) async {
- expect(rendered, isFalse);
- expect(id, equals(script_id));
- return script;
- }, count: 1)));
+ final repository = new ScriptRepositoryMock(
+ getter: expectAsync((isolate, id) async {
+ expect(rendered, isFalse);
+ expect(id, equals(script_id));
+ return script;
+ }, count: 1)
+ );
+ final e = new SourceLinkElement(isolate, location, repository);
document.body.append(e);
await e.onRendered.first;
rendered = true;
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn
index cf35eca..5f0a1ba 100644
--- a/runtime/vm/BUILD.gn
+++ b/runtime/vm/BUILD.gn
@@ -16,7 +16,10 @@
}
}
} else {
- libs = [ "runtime" ]
+ libs = [
+ "magenta",
+ "runtime",
+ ]
}
}
diff --git a/runtime/vm/class_table.cc b/runtime/vm/class_table.cc
index e8d8ae8..6a89478 100644
--- a/runtime/vm/class_table.cc
+++ b/runtime/vm/class_table.cc
@@ -211,6 +211,21 @@
#endif
+#if defined(DART_PRECOMPILER)
+void ClassTable::Remap(intptr_t* old_to_new_cid) {
+ intptr_t num_cids = NumCids();
+ RawClass** cls_by_old_cid = new RawClass*[num_cids];
+ for (intptr_t i = 0; i < num_cids; i++) {
+ cls_by_old_cid[i] = table_[i];
+ }
+ for (intptr_t i = 0; i < num_cids; i++) {
+ table_[old_to_new_cid[i]] = cls_by_old_cid[i];
+ }
+ delete[] cls_by_old_cid;
+}
+#endif
+
+
void ClassTable::VisitObjectPointers(ObjectPointerVisitor* visitor) {
ASSERT(visitor != NULL);
visitor->VisitPointers(reinterpret_cast<RawObject**>(&table_[0]), top_);
@@ -219,7 +234,7 @@
void ClassTable::Validate() {
Class& cls = Class::Handle();
- for (intptr_t i = kNumPredefinedCids; i < top_; i++) {
+ for (intptr_t cid = kNumPredefinedCids; cid < top_; cid++) {
// Some of the class table entries maybe NULL as we create some
// top level classes but do not add them to the list of anonymous
// classes in a library if there are no top level fields or functions.
@@ -227,9 +242,10 @@
// not written into a full snapshot and will not be recreated when
// we read back the full snapshot. These class slots end up with NULL
// entries.
- if (HasValidClassAt(i)) {
- cls = At(i);
+ if (HasValidClassAt(cid)) {
+ cls = At(cid);
ASSERT(cls.IsClass());
+ ASSERT(cls.id() == cid);
}
}
}
diff --git a/runtime/vm/class_table.h b/runtime/vm/class_table.h
index 1722dec..1ab7da1 100644
--- a/runtime/vm/class_table.h
+++ b/runtime/vm/class_table.h
@@ -191,6 +191,10 @@
void Unregister(intptr_t index);
#endif
+#if defined(DART_PRECOMPILER)
+ void Remap(intptr_t* old_to_new_cids);
+#endif
+
void VisitObjectPointers(ObjectPointerVisitor* visitor);
void Validate();
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index e64c399..560b600 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -730,7 +730,7 @@
void FinalizablePersistentHandle::Finalize(
Isolate* isolate, FinalizablePersistentHandle* handle) {
if (!handle->raw()->IsHeapObject()) {
- return;
+ return; // Free handle.
}
Dart_WeakPersistentHandleFinalizer callback = handle->callback();
ASSERT(callback != NULL);
@@ -1034,6 +1034,9 @@
REUSABLE_OBJECT_HANDLESCOPE(thread);
Object& ref = thread->ObjectHandle();
ref = Api::UnwrapHandle(object);
+ if (!ref.raw()->IsHeapObject()) {
+ return NULL;
+ }
FinalizablePersistentHandle* finalizable_ref =
FinalizablePersistentHandle::New(thread->isolate(),
ref,
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index d8a9299..ae0812c 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -1217,11 +1217,11 @@
Isolate::Current()->heap()->new_space()->Scavenge(invoke_api_callbacks);
}
- static void WaitForFinalizationTasks() {
+ static void WaitForGCTasks() {
Thread* thread = Thread::Current();
- Heap* heap = thread->isolate()->heap();
- MonitorLocker ml(heap->finalization_tasks_lock());
- while (heap->finalization_tasks() > 0) {
+ PageSpace* old_space = thread->isolate()->heap()->old_space();
+ MonitorLocker ml(old_space->tasks_lock());
+ while (old_space->tasks() > 0) {
ml.WaitWithSafepointCheck(thread);
}
}
@@ -1264,11 +1264,11 @@
EXPECT_EQ(40, peer8);
EXPECT_EQ(41, peer16);
Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
- GCTestHelper::WaitForFinalizationTasks();
+ GCTestHelper::WaitForGCTasks();
EXPECT_EQ(40, peer8);
EXPECT_EQ(41, peer16);
Isolate::Current()->heap()->CollectGarbage(Heap::kNew);
- GCTestHelper::WaitForFinalizationTasks();
+ GCTestHelper::WaitForGCTasks();
EXPECT_EQ(80, peer8);
EXPECT_EQ(82, peer16);
}
@@ -2380,6 +2380,13 @@
}
+static void UnreachedCallback(void* isolate_callback_data,
+ Dart_WeakPersistentHandle handle,
+ void* peer) {
+ UNREACHABLE();
+}
+
+
static void ExternalTypedDataFinalizer(void* isolate_callback_data,
Dart_WeakPersistentHandle handle,
void* peer) {
@@ -2405,39 +2412,25 @@
TransitionNativeToVM transition(thread);
EXPECT(peer == 0);
Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
- GCTestHelper::WaitForFinalizationTasks();
+ GCTestHelper::WaitForGCTasks();
EXPECT(peer == 0);
Isolate::Current()->heap()->CollectGarbage(Heap::kNew);
- GCTestHelper::WaitForFinalizationTasks();
+ GCTestHelper::WaitForGCTasks();
EXPECT(peer == 42);
}
}
-static Monitor* slow_finalizers_monitor = NULL;
-static intptr_t slow_finalizers_waiting = 0;
-
-
static void SlowFinalizer(void* isolate_callback_data,
Dart_WeakPersistentHandle handle,
void* peer) {
- {
- MonitorLocker ml(slow_finalizers_monitor);
- slow_finalizers_waiting++;
- while (slow_finalizers_waiting < 10) {
- ml.Wait();
- }
- ml.NotifyAll();
- }
-
+ OS::Sleep(10);
intptr_t* count = reinterpret_cast<intptr_t*>(peer);
- AtomicOperations::IncrementBy(count, 1);
+ (*count)++;
}
TEST_CASE(SlowFinalizer) {
- slow_finalizers_monitor = new Monitor();
-
intptr_t count = 0;
for (intptr_t i = 0; i < 10; i++) {
Dart_EnterScope();
@@ -2455,12 +2448,10 @@
{
TransitionNativeToVM transition(thread);
- GCTestHelper::WaitForFinalizationTasks();
+ GCTestHelper::WaitForGCTasks();
}
EXPECT_EQ(20, count);
-
- delete slow_finalizers_monitor;
}
@@ -2515,7 +2506,7 @@
{
TransitionNativeToVM transition(thread);
Isolate::Current()->heap()->CollectGarbage(Heap::kNew);
- GCTestHelper::WaitForFinalizationTasks();
+ GCTestHelper::WaitForGCTasks();
EXPECT(peer == 42);
}
}
@@ -2792,7 +2783,7 @@
TransitionNativeToVM transition(thread);
// Garbage collect new space again.
GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
- GCTestHelper::WaitForFinalizationTasks();
+ GCTestHelper::WaitForGCTasks();
}
{
@@ -2808,7 +2799,7 @@
TransitionNativeToVM transition(thread);
// Garbage collect old space again.
Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
- GCTestHelper::WaitForFinalizationTasks();
+ GCTestHelper::WaitForGCTasks();
}
{
@@ -2828,6 +2819,27 @@
}
+TEST_CASE(WeakPersistentHandleErrors) {
+ Dart_EnterScope();
+
+ // NULL callback.
+ Dart_Handle obj1 = NewString("new string");
+ EXPECT_VALID(obj1);
+ Dart_WeakPersistentHandle ref1 = Dart_NewWeakPersistentHandle(
+ obj1, NULL, 0, NULL);
+ EXPECT_EQ(ref1, static_cast<void*>(NULL));
+
+ // Immediate object.
+ Dart_Handle obj2 = Dart_NewInteger(0);
+ EXPECT_VALID(obj2);
+ Dart_WeakPersistentHandle ref2 = Dart_NewWeakPersistentHandle(
+ obj2, NULL, 0, WeakPersistentHandleCallback);
+ EXPECT_EQ(ref2, static_cast<void*>(NULL));
+
+ Dart_ExitScope();
+}
+
+
static void WeakPersistentHandlePeerFinalizer(void* isolate_callback_data,
Dart_WeakPersistentHandle handle,
void* peer) {
@@ -2853,7 +2865,7 @@
Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
EXPECT(peer == 0);
GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
- GCTestHelper::WaitForFinalizationTasks();
+ GCTestHelper::WaitForGCTasks();
EXPECT(peer == 42);
}
}
@@ -2880,7 +2892,7 @@
Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
EXPECT(peer == 0);
GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
- GCTestHelper::WaitForFinalizationTasks();
+ GCTestHelper::WaitForGCTasks();
EXPECT(peer == 0);
}
}
@@ -2941,7 +2953,7 @@
// Collect weakly referenced string, and promote strongly referenced string.
GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
- GCTestHelper::WaitForFinalizationTasks();
+ GCTestHelper::WaitForGCTasks();
EXPECT(heap->ExternalInWords(Heap::kNew) == 0);
EXPECT(heap->ExternalInWords(Heap::kOld) == kWeak2ExternalSize / kWordSize);
}
@@ -2952,7 +2964,7 @@
{
TransitionNativeToVM transition(thread);
Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
- GCTestHelper::WaitForFinalizationTasks();
+ GCTestHelper::WaitForGCTasks();
EXPECT(heap->ExternalInWords(Heap::kOld) == 0);
}
}
@@ -2998,7 +3010,7 @@
{
TransitionNativeToVM transition(thread);
Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
- GCTestHelper::WaitForFinalizationTasks();
+ GCTestHelper::WaitForGCTasks();
EXPECT(heap->ExternalInWords(Heap::kOld) == 0);
}
}
@@ -3045,17 +3057,18 @@
static const intptr_t kWeak1ExternalSize = 1 * KB;
Dart_WeakPersistentHandle weak2 = NULL;
static const intptr_t kWeak2ExternalSize = 2 * KB;
+ EXPECT_EQ(0, heap->ExternalInWords(Heap::kOld));
{
Dart_EnterScope();
Dart_Handle dart_true = Dart_True(); // VM heap object.
EXPECT_VALID(dart_true);
weak1 = Dart_NewWeakPersistentHandle(
- dart_true, NULL, kWeak1ExternalSize, NopCallback);
+ dart_true, NULL, kWeak1ExternalSize, UnreachedCallback);
EXPECT_VALID(AsHandle(weak1));
- Dart_Handle zero = Dart_NewInteger(0); // Smi.
+ Dart_Handle zero = Dart_False(); // VM heap object.
EXPECT_VALID(zero);
weak2 = Dart_NewWeakPersistentHandle(
- zero, NULL, kWeak2ExternalSize, NopCallback);
+ zero, NULL, kWeak2ExternalSize, UnreachedCallback);
EXPECT_VALID(AsHandle(weak2));
// Both should be charged to old space.
EXPECT(heap->ExternalInWords(Heap::kOld) ==
@@ -3065,6 +3078,7 @@
Dart_Isolate isolate = reinterpret_cast<Dart_Isolate>(Isolate::Current());
Dart_DeleteWeakPersistentHandle(isolate, weak1);
Dart_DeleteWeakPersistentHandle(isolate, weak2);
+ EXPECT_EQ(0, heap->ExternalInWords(Heap::kOld));
{
TransitionNativeToVM transition(thread);
Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
@@ -8824,7 +8838,7 @@
{
TransitionNativeToVM transition(thread);
Isolate::Current()->heap()->CollectAllGarbage();
- GCTestHelper::WaitForFinalizationTasks();
+ GCTestHelper::WaitForGCTasks();
}
EXPECT_EQ(80, peer8);
EXPECT_EQ(82, peer16);
diff --git a/runtime/vm/dart_api_state.cc b/runtime/vm/dart_api_state.cc
index be30a2d..ed6ac3e 100644
--- a/runtime/vm/dart_api_state.cc
+++ b/runtime/vm/dart_api_state.cc
@@ -19,9 +19,9 @@
isolate_(isolate),
queue_(queue) {
ASSERT(FLAG_background_finalization);
- MonitorLocker ml(isolate->heap()->finalization_tasks_lock());
- isolate->heap()->set_finalization_tasks(
- isolate->heap()->finalization_tasks() + 1);
+ PageSpace* old_space = isolate->heap()->old_space();
+ MonitorLocker ml(old_space->tasks_lock());
+ old_space->set_tasks(old_space->tasks() + 1);
ml.Notify();
}
@@ -46,9 +46,9 @@
Thread::ExitIsolateAsHelper();
{
- Heap* heap = isolate_->heap();
- MonitorLocker ml(heap->finalization_tasks_lock());
- heap->set_finalization_tasks(heap->finalization_tasks() - 1);
+ PageSpace* old_space = isolate_->heap()->old_space();
+ MonitorLocker ml(old_space->tasks_lock());
+ old_space->set_tasks(old_space->tasks() - 1);
ml.Notify();
}
}
diff --git a/runtime/vm/heap.cc b/runtime/vm/heap.cc
index 83bacb1..b9a74c7 100644
--- a/runtime/vm/heap.cc
+++ b/runtime/vm/heap.cc
@@ -35,8 +35,6 @@
old_space_(this, max_old_gen_words, max_external_words),
barrier_(new Monitor()),
barrier_done_(new Monitor()),
- finalization_tasks_lock_(new Monitor()),
- finalization_tasks_(0),
read_only_(false),
gc_new_space_in_progress_(false),
gc_old_space_in_progress_(false) {
@@ -53,7 +51,6 @@
Heap::~Heap() {
delete barrier_;
delete barrier_done_;
- delete finalization_tasks_lock_;
for (int sel = 0;
sel < kNumWeakSelectors;
diff --git a/runtime/vm/heap.h b/runtime/vm/heap.h
index d90adc4..63f35d8 100644
--- a/runtime/vm/heap.h
+++ b/runtime/vm/heap.h
@@ -253,10 +253,6 @@
Monitor* barrier() const { return barrier_; }
Monitor* barrier_done() const { return barrier_done_; }
- Monitor* finalization_tasks_lock() const { return finalization_tasks_lock_; }
- intptr_t finalization_tasks() const { return finalization_tasks_; }
- void set_finalization_tasks(intptr_t count) { finalization_tasks_ = count; }
-
void SetupExternalPage(void* pointer, uword size, bool is_executable) {
old_space_.SetupExternalPage(pointer, size, is_executable);
}
@@ -350,9 +346,6 @@
Monitor* barrier_;
Monitor* barrier_done_;
- Monitor* finalization_tasks_lock_;
- intptr_t finalization_tasks_;
-
// GC stats collection.
GCStats stats_;
@@ -365,6 +358,7 @@
bool gc_old_space_in_progress_;
friend class Become; // VisitObjectPointers
+ friend class Precompiler; // VisitObjects
friend class ServiceEvent;
friend class PageSpace; // VerifyGC
friend class IsolateReloadContext; // VisitObjects
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index 612d97e..f583fa1 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -1772,13 +1772,11 @@
// We need temporaries for field object.
summary->set_temp(0, Location::RequiresRegister());
return summary;
- } else {
- LocationSummary* summary = new(zone) LocationSummary(
- zone, kNumInputs, 0, LocationSummary::kNoCall);
- summary->set_in(0, Location::RequiresRegister());
- return summary;
}
- UNREACHABLE();
+ LocationSummary* summary = new(zone) LocationSummary(
+ zone, kNumInputs, 0, LocationSummary::kNoCall);
+ summary->set_in(0, Location::RequiresRegister());
+ return summary;
}
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 3c6c88b..7d203bd 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -1736,20 +1736,10 @@
if (heap_ != NULL) {
// Wait for any concurrent GC tasks to finish before shutting down.
// TODO(koda): Support faster sweeper shutdown (e.g., after current page).
- {
- PageSpace* old_space = heap_->old_space();
- MonitorLocker ml(old_space->tasks_lock());
- while (old_space->tasks() > 0) {
- ml.Wait();
- }
- }
-
- // Wait for background finalization to finish before shutting down.
- {
- MonitorLocker ml(heap_->finalization_tasks_lock());
- while (heap_->finalization_tasks() > 0) {
- ml.Wait();
- }
+ PageSpace* old_space = heap_->old_space();
+ MonitorLocker ml(old_space->tasks_lock());
+ while (old_space->tasks() > 0) {
+ ml.Wait();
}
}
@@ -1895,7 +1885,8 @@
raw_class = class_table()->At(cid);
#endif // !PRODUCT
ASSERT(raw_class != NULL);
- ASSERT(raw_class->ptr()->id_ == cid);
+ // This is temporarily untrue during a class id remap.
+ // ASSERT(raw_class->ptr()->id_ == cid);
return raw_class;
}
diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc
index 4fa23bc..11a7b3b 100644
--- a/runtime/vm/precompiler.cc
+++ b/runtime/vm/precompiler.cc
@@ -198,6 +198,8 @@
// because their class hasn't been finalized yet.
FinalizeAllClasses();
+ SortClasses();
+
// Precompile static initializers to compute result type information.
PrecompileStaticInitializers();
@@ -344,8 +346,16 @@
function.ClearICDataArray();
}
};
- ClearCodeFunctionVisitor visitor;
- VisitFunctions(&visitor);
+ ClearCodeFunctionVisitor function_visitor;
+ VisitFunctions(&function_visitor);
+
+ class ClearCodeClassVisitor : public ClassVisitor {
+ void Visit(const Class& cls) {
+ cls.DisableAllocationStub();
+ }
+ };
+ ClearCodeClassVisitor class_visitor;
+ VisitClasses(&class_visitor);
}
@@ -2206,6 +2216,147 @@
}
+void Precompiler::SortClasses() {
+ ClassTable* table = I->class_table();
+ intptr_t num_cids = table->NumCids();
+ intptr_t* old_to_new_cid = new intptr_t[num_cids];
+ for (intptr_t cid = 0; cid < kNumPredefinedCids; cid++) {
+ old_to_new_cid[cid] = cid; // The predefined classes cannot change cids.
+ }
+ for (intptr_t cid = kNumPredefinedCids; cid < num_cids; cid++) {
+ old_to_new_cid[cid] = -1;
+ }
+
+ intptr_t next_new_cid = kNumPredefinedCids;
+ GrowableArray<intptr_t> dfs_stack;
+ Class& cls = Class::Handle(Z);
+ GrowableObjectArray& subclasses = GrowableObjectArray::Handle(Z);
+
+ // Object doesn't use its subclasses list.
+ for (intptr_t cid = kNumPredefinedCids; cid < num_cids; cid++) {
+ if (!table->HasValidClassAt(cid)) {
+ continue;
+ }
+ cls = table->At(cid);
+ if (cls.is_patch()) {
+ continue;
+ }
+ if (cls.SuperClass() == I->object_store()->object_class()) {
+ dfs_stack.Add(cid);
+ }
+ }
+
+ while (dfs_stack.length() > 0) {
+ intptr_t cid = dfs_stack.RemoveLast();
+ ASSERT(table->HasValidClassAt(cid));
+ cls = table->At(cid);
+ ASSERT(!cls.IsNull());
+ if (old_to_new_cid[cid] == -1) {
+ old_to_new_cid[cid] = next_new_cid++;
+ if (FLAG_trace_precompiler) {
+ THR_Print("%" Pd ": %s, was %" Pd "\n",
+ old_to_new_cid[cid], cls.ToCString(), cid);
+ }
+ }
+ subclasses = cls.direct_subclasses();
+ if (!subclasses.IsNull()) {
+ for (intptr_t i = 0; i < subclasses.Length(); i++) {
+ cls ^= subclasses.At(i);
+ ASSERT(!cls.IsNull());
+ dfs_stack.Add(cls.id());
+ }
+ }
+ }
+
+ // Top-level classes, typedefs, patch classes, etc.
+ for (intptr_t cid = kNumPredefinedCids; cid < num_cids; cid++) {
+ if (old_to_new_cid[cid] == -1) {
+ old_to_new_cid[cid] = next_new_cid++;
+ if (FLAG_trace_precompiler && table->HasValidClassAt(cid)) {
+ cls = table->At(cid);
+ THR_Print("%" Pd ": %s, was %" Pd "\n",
+ old_to_new_cid[cid], cls.ToCString(), cid);
+ }
+ }
+ }
+ ASSERT(next_new_cid == num_cids);
+
+ RemapClassIds(old_to_new_cid);
+ delete[] old_to_new_cid;
+}
+
+
+class CidRewriteVisitor : public ObjectVisitor {
+ public:
+ explicit CidRewriteVisitor(intptr_t* old_to_new_cids)
+ : old_to_new_cids_(old_to_new_cids) { }
+
+ intptr_t Map(intptr_t cid) {
+ ASSERT(cid != -1);
+ return old_to_new_cids_[cid];
+ }
+
+ void VisitObject(RawObject* obj) {
+ if (obj->IsClass()) {
+ RawClass* cls = Class::RawCast(obj);
+ cls->ptr()->id_ = Map(cls->ptr()->id_);
+ } else if (obj->IsField()) {
+ RawField* field = Field::RawCast(obj);
+ field->ptr()->guarded_cid_ = Map(field->ptr()->guarded_cid_);
+ field->ptr()->is_nullable_ = Map(field->ptr()->is_nullable_);
+ } else if (obj->IsTypeParameter()) {
+ RawTypeParameter* param = TypeParameter::RawCast(obj);
+ param->ptr()->parameterized_class_id_ =
+ Map(param->ptr()->parameterized_class_id_);
+ } else if (obj->IsType()) {
+ RawType* type = Type::RawCast(obj);
+ RawObject* id = type->ptr()->type_class_id_;
+ if (!id->IsHeapObject()) {
+ type->ptr()->type_class_id_ =
+ Smi::New(Map(Smi::Value(Smi::RawCast(id))));
+ }
+ } else {
+ intptr_t old_cid = obj->GetClassId();
+ intptr_t new_cid = Map(old_cid);
+ if (old_cid != new_cid) {
+ // Don't touch objects that are unchanged. In particular, Instructions,
+ // which are write-protected.
+ obj->SetClassId(new_cid);
+ }
+ }
+ }
+
+ private:
+ intptr_t* old_to_new_cids_;
+};
+
+
+void Precompiler::RemapClassIds(intptr_t* old_to_new_cid) {
+ // Code, ICData, allocation stubs have now-invalid cids.
+ ClearAllCode();
+
+ {
+ HeapIterationScope his;
+
+ // Update the class table. Do it before rewriting cids in headers, as the
+ // heap walkers load an object's size *after* calling the visitor.
+ I->class_table()->Remap(old_to_new_cid);
+
+ // Rewrite cids in headers and cids in Classes, Fields, Types and
+ // TypeParameters.
+ {
+ CidRewriteVisitor visitor(old_to_new_cid);
+ I->heap()->VisitObjects(&visitor);
+ }
+ }
+
+#if defined(DEBUG)
+ I->class_table()->Validate();
+ I->heap()->Verify();
+#endif
+}
+
+
void Precompiler::ResetPrecompilerState() {
changed_ = false;
function_count_ = 0;
diff --git a/runtime/vm/precompiler.h b/runtime/vm/precompiler.h
index ad7f0ca..38e16fe 100644
--- a/runtime/vm/precompiler.h
+++ b/runtime/vm/precompiler.h
@@ -335,6 +335,8 @@
void VisitClasses(ClassVisitor* visitor);
void FinalizeAllClasses();
+ void SortClasses();
+ void RemapClassIds(intptr_t* old_to_new_cid);
Thread* thread() const { return thread_; }
Zone* zone() const { return zone_; }
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc
index d6fcec3..067f382 100644
--- a/runtime/vm/profiler.cc
+++ b/runtime/vm/profiler.cc
@@ -335,11 +335,9 @@
char* native_symbol_name =
NativeSymbolResolver::LookupSymbolName(pc, &start);
if (native_symbol_name == NULL) {
- OS::PrintErr("Frame[%" Pd "] = `unknown symbol` [0x%" Px "]\n",
- frame_index, pc);
+ OS::PrintErr(" [0x%" Pp "] Unknown symbol\n", pc);
} else {
- OS::PrintErr("Frame[%" Pd "] = `%s` [0x%" Px "]\n",
- frame_index, native_symbol_name, pc);
+ OS::PrintErr(" [0x%" Pp "] %s\n", pc, native_symbol_name);
NativeSymbolResolver::FreeSymbolName(native_symbol_name);
}
}
@@ -1033,7 +1031,7 @@
fp,
sp);
}
- OS::PrintErr("-- End of DumpStackTrace");
+ OS::PrintErr("-- End of DumpStackTrace\n");
}
diff --git a/runtime/vm/profiler_service.cc b/runtime/vm/profiler_service.cc
index 6aed93c..d5ffcb9 100644
--- a/runtime/vm/profiler_service.cc
+++ b/runtime/vm/profiler_service.cc
@@ -816,6 +816,7 @@
return hi;
}
UNREACHABLE();
+ return -1;
}
private:
@@ -2640,6 +2641,7 @@
return func->Name();
}
UNREACHABLE();
+ return NULL;
}
@@ -2663,6 +2665,7 @@
return func->inclusive_ticks();
}
UNREACHABLE();
+ return -1;
}
@@ -2678,6 +2681,7 @@
return func->exclusive_ticks();
}
UNREACHABLE();
+ return -1;
}
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index 73070ac..e4200b9 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -637,7 +637,6 @@
intptr_t RawICData::VisitICDataPointers(RawICData* raw_obj,
ObjectPointerVisitor* visitor) {
- // Make sure that we got here with the tagged pointer as this.
visitor->VisitPointers(raw_obj->from(), raw_obj->to());
return ICData::InstanceSize();
}
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 1e975d7..14a9895 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -539,6 +539,11 @@
return ClassIdTag::decode(tags);
}
+ void SetClassId(intptr_t new_cid) {
+ uword tags = ptr()->tags_;
+ ptr()->tags_ = ClassIdTag::update(new_cid, tags);
+ }
+
template<class TagBitField>
void UpdateTagBit(bool value) {
uword tags = ptr()->tags_;
@@ -596,6 +601,7 @@
friend class Become; // GetClassId
friend class Bigint;
friend class ByteBuffer;
+ friend class CidRewriteVisitor;
friend class Closure;
friend class Code;
friend class Double;
@@ -719,6 +725,7 @@
friend class RawInstructions;
friend class SnapshotReader;
friend class InstanceSerializationCluster;
+ friend class CidRewriteVisitor;
};
@@ -947,6 +954,8 @@
int8_t guarded_list_length_in_object_offset_;
uint8_t kind_bits_; // static, final, const, has initializer....
+
+ friend class CidRewriteVisitor;
};
@@ -1681,6 +1690,8 @@
}
TokenPosition token_pos_;
int8_t type_state_;
+
+ friend class CidRewriteVisitor;
};
@@ -1713,6 +1724,8 @@
TokenPosition token_pos_;
int16_t index_;
int8_t type_state_;
+
+ friend class CidRewriteVisitor;
};
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index fe73042..104d22c 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -3548,6 +3548,10 @@
}
void Append(FinalizablePersistentHandle* weak_persistent_handle) {
+ if (!weak_persistent_handle->raw()->IsHeapObject()) {
+ return; // Free handle.
+ }
+
JSONObject obj(handles_);
obj.AddProperty("type", "_WeakPersistentHandle");
const Object& object =
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index c26229d..7a937b3 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -31129,7 +31129,7 @@
* For more examples of using this API, see
* [localstorage_test.dart](http://code.google.com/p/dart/source/browse/branches/bleeding_edge/dart/tests/html/localstorage_test.dart).
* For details on using the Map API, see the
- * [Maps](http://www.dartlang.org/docs/library-tour/#maps-aka-dictionaries-or-hashes)
+ * [Maps](https://www.dartlang.org/guides/libraries/library-tour#maps)
* section of the library tour.
*/
@DomName('Storage')
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 0b536b6..e007fc3 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -35026,7 +35026,7 @@
* For more examples of using this API, see
* [localstorage_test.dart](http://code.google.com/p/dart/source/browse/branches/bleeding_edge/dart/tests/html/localstorage_test.dart).
* For details on using the Map API, see the
- * [Maps](http://www.dartlang.org/docs/library-tour/#maps-aka-dictionaries-or-hashes)
+ * [Maps](https://www.dartlang.org/guides/libraries/library-tour#maps)
* section of the library tour.
*/
@DomName('Storage')
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index a0dd69f..cd1f320 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -496,6 +496,184 @@
LibTest/core/Uri/Uri_A06_t03: Slow, Pass
LibTest/math/Point/operator_mult_A02_t01: RuntimeError # Issue 1533
+[ $compiler == dart2js && $fast_startup ]
+Language/Classes/Instance_Methods/Operators/unary_minus: Fail # mirrors not supported
+Language/Expressions/Null/instance_of_class_null_t01: Fail # mirrors not supported
+Language/Metadata/before_class_t01: Fail # mirrors not supported
+Language/Metadata/before_ctor_t01: Fail # mirrors not supported
+Language/Metadata/before_ctor_t02: Fail # mirrors not supported
+Language/Metadata/before_export_t01: Fail # mirrors not supported
+Language/Metadata/before_factory_t01: Fail # mirrors not supported
+Language/Metadata/before_function_t01: Fail # mirrors not supported
+Language/Metadata/before_function_t02: Fail # mirrors not supported
+Language/Metadata/before_function_t03: Fail # mirrors not supported
+Language/Metadata/before_function_t04: Fail # mirrors not supported
+Language/Metadata/before_function_t05: Fail # mirrors not supported
+Language/Metadata/before_function_t06: Fail # mirrors not supported
+Language/Metadata/before_function_t07: Fail # mirrors not supported
+Language/Metadata/before_import_t01: Fail # mirrors not supported
+Language/Metadata/before_library_t01: Fail # mirrors not supported
+Language/Metadata/before_param_t01: Fail # mirrors not supported
+Language/Metadata/before_param_t02: Fail # mirrors not supported
+Language/Metadata/before_param_t03: Fail # mirrors not supported
+Language/Metadata/before_param_t04: Fail # mirrors not supported
+Language/Metadata/before_param_t05: Fail # mirrors not supported
+Language/Metadata/before_param_t06: Fail # mirrors not supported
+Language/Metadata/before_param_t07: Fail # mirrors not supported
+Language/Metadata/before_param_t08: Fail # mirrors not supported
+Language/Metadata/before_param_t09: Fail # mirrors not supported
+Language/Metadata/before_type_param_t01: Fail # mirrors not supported
+Language/Metadata/before_typedef_t01: Fail # mirrors not supported
+Language/Metadata/before_variable_t01: Fail # mirrors not supported
+Language/Metadata/before_variable_t02: Fail # mirrors not supported
+Language/Metadata/compilation_t01: Pass # mirrors not supported, fails for the wrong reason
+Language/Metadata/compilation_t02: Pass # mirrors not supported, fails for the wrong reason
+Language/Metadata/compilation_t03: Pass # mirrors not supported, fails for the wrong reason
+Language/Metadata/compilation_t04: Pass # mirrors not supported, fails for the wrong reason
+Language/Metadata/compilation_t05: Pass # mirrors not supported, fails for the wrong reason
+Language/Metadata/compilation_t06: Pass # mirrors not supported, fails for the wrong reason
+Language/Metadata/compilation_t07: Pass # mirrors not supported, fails for the wrong reason
+Language/Metadata/compilation_t08: Pass # mirrors not supported, fails for the wrong reason
+Language/Metadata/compilation_t09: Pass # mirrors not supported, fails for the wrong reason
+Language/Metadata/compilation_t10: Pass # mirrors not supported, fails for the wrong reason
+Language/Metadata/compilation_t11: Pass # mirrors not supported, fails for the wrong reason
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-001_t01: Fail # custom elements not supported
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-004_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-004_t02: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-005_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-006_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/methods/elements-001_t01: Fail # custom elements not supported
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/methods/elements-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/methods/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/methods/test-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/methods/test-003_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-event-interface/event-path-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-007_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-008_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-009_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-010_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-011_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-012_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-013_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-001_t01: Fail # custom elements not supported
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-006_t01: Fail # custom elements not supported
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-006_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-007_t01: Fail # custom elements not supported
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-007_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-010_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-003_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-004_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-004_t02: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-005_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-006_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-003_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-003_t02: Fail # custom elements not supported
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-003_t02: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-004_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-005_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/event-dispatch/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/event-dispatch/test-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/event-dispatch/test-003_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/event-retargeting/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/event-retargeting/test-002_t01: Fail # custom elements not supported
+WebPlatformTest/shadow-dom/events/event-retargeting/test-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/event-retargeting/test-003_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/event-retargeting/test-004_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-003_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-004_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-005_t01: Fail # custom elements not supported
+WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-005_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-006_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-007_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-008_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-009_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t02: Fail # please triage
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t03: Fail # please triage
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t04: Fail # please triage
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t05: Fail # please triage
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t06: Fail # please triage
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-003_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/retargeting-relatedtarget/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/retargeting-relatedtarget/test-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/retargeting-relatedtarget/test-003_t01: Fail # please triage
+WebPlatformTest/shadow-dom/html-elements-and-their-shadow-trees/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/html-elements-and-their-shadow-trees/test-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/html-elements-and-their-shadow-trees/test-003_t01: Fail # please triage
+WebPlatformTest/shadow-dom/html-elements-and-their-shadow-trees/test-004_t01: Fail # custom elements not supported
+WebPlatformTest/shadow-dom/html-elements-and-their-shadow-trees/test-004_t01: Fail # please triage
+WebPlatformTest/shadow-dom/html-elements-in-shadow-trees/html-forms/test-001_t01: Fail # custom elements not supported
+WebPlatformTest/shadow-dom/html-elements-in-shadow-trees/html-forms/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/html-elements-in-shadow-trees/html-forms/test-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/html-elements-in-shadow-trees/inert-html-elements/test-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/composition/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/custom-pseudo-elements/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/distributed-pseudo-element/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/distributed-pseudo-element/test-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/hosting-multiple-shadow-trees/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/hosting-multiple-shadow-trees/test-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/hosting-multiple-shadow-trees/test-003_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/lower-boundary-encapsulation/distribution-003_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/lower-boundary-encapsulation/test-003_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/lower-boundary-encapsulation/test-004_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/lower-boundary-encapsulation/test-005_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/nested-shadow-trees/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/rendering-shadow-trees/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/reprojection/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/satisfying-matching-criteria/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/satisfying-matching-criteria/test-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/satisfying-matching-criteria/test-003_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/satisfying-matching-criteria/test-004_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/satisfying-matching-criteria/test-005_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/satisfying-matching-criteria/test-006_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/satisfying-matching-criteria/test-017_t01: Fail # custom elements not supported
+WebPlatformTest/shadow-dom/shadow-trees/satisfying-matching-criteria/test-017_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/dom-tree-accessors-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/ownerdocument-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/ownerdocument-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/selectors-api-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/selectors-api-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/shadow-root-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-005_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-007_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-009_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-011_t01: Fail # please triage
+WebPlatformTest/shadow-dom/testcommon: Fail # mirrors not supported
+
+[ $compiler == dart2js && $fast_startup && $runtime == jsshell ]
+LibTest/isolate/ReceivePort/asBroadcastStream_A03_t01: Fail # please triage
+
+[ $compiler == dart2js && $fast_startup && $browser ]
+LayoutTests/fast/dom/custom/document-register-on-create-callback_t01: Fail # please triage
+LayoutTests/fast/dom/custom/unresolved-pseudoclass_t01: Fail # please triage
+WebPlatformTest/custom-elements/concepts/type_A01_t01: Fail # custom elements not supported
+LayoutTests/fast/dom/custom/attribute-changed-callback_t01: Fail # custom elements not supported
+LayoutTests/fast/dom/custom/created-callback_t01: Fail # please triage
+LayoutTests/fast/dom/custom/document-register-namespace_t01: Fail # please triage
+LayoutTests/fast/dom/custom/document-register-type-extensions_t01: Fail # please triage
+LayoutTests/fast/dom/custom/element-type_t01: Fail # custom elements not supported
+LayoutTests/fast/dom/custom/element-upgrade_t01: Fail # please triage
+LayoutTests/fast/dom/custom/type-extensions_t01: Fail # custom elements not supported
+WebPlatformTest/custom-elements/concepts/type_A07_t01: Fail # custom elements not supported
+WebPlatformTest/custom-elements/concepts/type_A08_t01: Fail # please triage
+WebPlatformTest/custom-elements/instantiating/createElementNS_A01_t01: Fail # please triage
+WebPlatformTest/custom-elements/instantiating/createElementNS_A04_t01: Fail # custom elements not supported
+WebPlatformTest/custom-elements/instantiating/createElementNS_A05_t01: Fail # custom elements not supported
+WebPlatformTest/custom-elements/instantiating/createElement_A01_t01: Fail # please triage
+WebPlatformTest/custom-elements/instantiating/createElement_A05_t01: Fail # please triage
+WebPlatformTest/custom-elements/instantiating/isAttribute_A03_t01: Fail # please triage
+WebPlatformTest/custom-elements/instantiating/localName_A01_t01: Fail # please triage
+
+
[ $compiler == dart2js && $checked != true ]
Language/Expressions/Property_Extraction/General_Super_Property_Extraction/getter_lookup_t02: Timeout, Skip # Please triage this failure
Language/Expressions/Property_Extraction/Super_Closurization/setter_closurization_t09: CompileTimeError # Please triage this failure
@@ -1442,7 +1620,6 @@
WebPlatformTest/Utils/test/asyncTestFail_t01: RuntimeError # Please triage this failure
WebPlatformTest/Utils/test/asyncTestFail_t02: RuntimeError # Please triage this failure
WebPlatformTest/Utils/test/asyncTestTimeout_t01: Skip # Times out. Please triage this failure
-WebPlatformTest/custom-elements/concepts/type_A03_t01: RuntimeError # Please triage this failure
WebPlatformTest/custom-elements/concepts/type_A05_t01: RuntimeError # Please triage this failure
WebPlatformTest/custom-elements/concepts/type_A06_t01: RuntimeError # Please triage this failure
WebPlatformTest/custom-elements/instantiating/createElementNS_A02_t01: RuntimeError # Issue 25155
@@ -1601,6 +1778,15 @@
WebPlatformTest/webstorage/event_constructor_t01: RuntimeError # Please triage this failure
WebPlatformTest/webstorage/event_constructor_t02: RuntimeError # Please triage this failure
+[ $compiler == dart2js && $runtime == chrome && $fast_startup ]
+WebPlatformTest/custom-elements/concepts/type_A04_t01: RuntimeError # Please triage this failure
+WebPlatformTest/custom-elements/instantiating/createElement_A04_t01: RuntimeError # Please triage this failure
+WebPlatformTest/custom-elements/instantiating/isAttribute_A02_t01: RuntimeError # Please triage this failure
+WebPlatformTest/custom-elements/instantiating/namespace_A01_t01: RuntimeError # Please triage this failure
+
+[ $compiler == dart2js && $runtime == chrome && $fast_startup == false ]
+WebPlatformTest/custom-elements/concepts/type_A03_t01: RuntimeError # Please triage this failure
+
[ $compiler == dart2js && $runtime == chrome && $checked ]
LayoutTests/fast/css-intrinsic-dimensions/css-tables_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-absolutes_t01: RuntimeError # Please triage this failure
@@ -3205,7 +3391,6 @@
[ $compiler == dart2js && $runtime == ff && $system == linux]
LayoutTests/fast/canvas/webgl/*: Timeout, Pass # Issue 26725
-LayoutTests/fast/canvas/canvas-composite-text-alpha_t01: RuntimeError # co19 issue 16
LayoutTests/fast/text/whitespace/nowrap-line-break-after-white-space_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/oes-element-index-uint_t01: Skip # Times out always
LayoutTests/fast/canvas/webgl/texture-complete_t01: Skip # Times out sometimes
@@ -4020,7 +4205,6 @@
LibTest/html/Element/getClientRects_A01_t02: RuntimeError # Please triage this failure
LibTest/html/Element/getNamespacedAttributes_A01_t01: RuntimeError # Please triage this failure
LibTest/html/Element/isContentEditable_A01_t01: RuntimeError # Please triage this failure
-LibTest/html/Element/isContentEditable_A02_t01: RuntimeError # Please triage this failure
LibTest/html/Element/isTagSupported_A01_t01: RuntimeError # Please triage this failure
LibTest/html/Element/isTagSupported_A01_t02: RuntimeError # Please triage this failure
LibTest/html/Element/leftView_A01_t01: RuntimeError # Please triage this failure
@@ -4365,7 +4549,6 @@
LayoutTests/fast/forms/datalist/datalist-child-validation_t01: RuntimeError # Fails 10 out of 10.
LayoutTests/fast/overflow/scrollbar-restored_t01: RuntimeError # Fails 10 out of 10.
LibTest/html/Element/isContentEditable_A01_t01: RuntimeError # Fails 10 out of 10.
-LibTest/html/Element/isContentEditable_A02_t01: RuntimeError # Fails 10 out of 10.
LibTest/html/IFrameElement/isContentEditable_A01_t01: RuntimeError, Pass # Fails 19 out of 20.
LayoutTests/fast/flexbox/repaint-scrollbar_t01: Pass, RuntimeError # Fails 2 out of 10.
@@ -4378,6 +4561,9 @@
LayoutTests/fast/canvas/webgl/glsl-conformance_t01: Skip # Times out 1 out of 20.
+[ $compiler == dart2js && $runtime == safari && $fast_startup == false ]
+LibTest/html/Element/isContentEditable_A02_t01: RuntimeError # Fails 10 out of 10.
+
[ $compiler == dart2js && $runtime == safarimobilesim ]
LayoutTests/fast/alignment/parse-align-items_t01: RuntimeError # Please triage this failure
LayoutTests/fast/alignment/parse-align-self_t01: RuntimeError # Please triage this failure
@@ -7702,6 +7888,9 @@
WebPlatformTest/webstorage/storage_builtins_t01: RuntimeError # Please triage this failure
WebPlatformTest/webstorage/storage_local_setitem_quotaexceedederr_t01: Skip # Times out. Please triage this failure
+[ $compiler == dart2js && $runtime == ie10 && $fast_startup ]
+LayoutTests/fast/canvas/canvas-composite-image_t01: RuntimeError
+
[ $compiler == dart2js && $runtime == ie11 ]
Language/Variables/implicit_setter_void_t07: Skip # Times out. Please triage this failure
Language/Functions/Formal_Parameters/scope_t01: Skip # Times out. Please triage this failure
diff --git a/tests/compiler/dart2js/kernel/helper.dart b/tests/compiler/dart2js/kernel/helper.dart
index 37dfe15..30512d8 100644
--- a/tests/compiler/dart2js/kernel/helper.dart
+++ b/tests/compiler/dart2js/kernel/helper.dart
@@ -36,5 +36,5 @@
Future check(String code, {String entry: 'main'}) async {
var original = await compile(code, entry: entry, useKernel: false);
var kernel = await compile(code, entry: entry, useKernel: true);
- expect(original, kernel);
+ expect(kernel, original);
}
diff --git a/tests/compiler/dart2js/kernel/simple_function_test.dart b/tests/compiler/dart2js/kernel/simple_function_test.dart
new file mode 100644
index 0000000..5b1985d
--- /dev/null
+++ b/tests/compiler/dart2js/kernel/simple_function_test.dart
@@ -0,0 +1,43 @@
+import 'package:test/test.dart';
+
+import 'helper.dart' show check;
+
+main() {
+ group('compile function that returns a value', () {
+ test('constant int', () {
+ return check('main() { return 1; }');
+ });
+
+ test('constant double', () {
+ return check('main() { return 1.0; }');
+ });
+
+ test('constant string', () {
+ return check('main() { return "hello"; }');
+ });
+
+ test('constant bool', () {
+ return check('main() { return true; }');
+ });
+
+ test('constant symbol', () {
+ return check('main() { return #hello; }');
+ });
+
+ test('null', () {
+ return check('main() { return null; }');
+ });
+ });
+
+ test('compile function that returns its argument', () {
+ String code = '''
+ foo(x) {
+ return x;
+ }
+
+ main() {
+ foo(1);
+ }''';
+ return check(code, entry: 'foo');
+ });
+}
diff --git a/tests/compiler/dart2js_extra/dart2js_extra.status b/tests/compiler/dart2js_extra/dart2js_extra.status
index 6fa9843..596f35a 100644
--- a/tests/compiler/dart2js_extra/dart2js_extra.status
+++ b/tests/compiler/dart2js_extra/dart2js_extra.status
@@ -14,6 +14,44 @@
variable_type_test/03: Fail, OK
variable_type_test/01: Fail, OK
+[ $compiler == dart2js && $fast_startup ]
+21666_test: Fail # mirrors not supported
+23056_test: Fail # mirrors not supported
+closure_type_reflection2_test: Fail # mirrors not supported
+closure_type_reflection_test: Fail # mirrors not supported
+deferred/deferred_mirrors1_lib: Fail # mirrors not supported
+deferred/deferred_mirrors1_test: Fail # mirrors not supported
+deferred/deferred_mirrors2_lazy: Fail # mirrors not supported
+deferred/deferred_mirrors2_lib3: Fail # mirrors not supported
+deferred/deferred_mirrors2_test: Fail # mirrors not supported
+inference_nsm_mirrors_test: Fail # mirrors not supported
+invalid_annotation2_test/none: Fail # mirrors not supported
+invalid_annotation2_test/01: Pass # mirrors not supported, passes for the wrong reason
+lookup_map/dead_entry_through_mirrors_test: Fail # mirrors not supported
+lookup_map/live_entry_through_mirrors_test: Fail # mirrors not supported
+lookup_map/live_entry_through_mirrors_used_test: Fail # mirrors not supported
+mirror_enqueuer_regression_test: Fail # mirrors not supported
+mirror_invalid_field_access2_test: Fail # mirrors not supported
+mirror_invalid_field_access3_test: Fail # mirrors not supported
+mirror_invalid_field_access4_test: Fail # mirrors not supported
+mirror_invalid_field_access_test: Fail # mirrors not supported
+mirror_invalid_invoke2_test: Fail # mirrors not supported
+mirror_invalid_invoke3_test: Fail # mirrors not supported
+mirror_invalid_invoke_test: Fail # mirrors not supported
+mirror_printer_test: Fail # mirrors not supported
+mirror_test: Fail # mirrors not supported
+mirror_type_inference_field2_test: Fail # mirrors not supported
+mirror_type_inference_field_test: Fail # mirrors not supported
+mirror_type_inference_function_test: Fail # mirrors not supported
+mirrors_declarations_filtering_test: Fail # mirrors not supported
+mirrors_used_closure_test: Fail # mirrors not supported
+mirrors_used_metatargets_test: Fail # mirrors not supported
+mirrors_used_native_test: Fail # mirrors not supported
+mirrors_used_warning2_test: Fail # mirrors not supported
+mirrors_used_warning_test: Fail # mirrors not supported
+no_such_method_mirrors_test: Fail # mirrors not supported
+reflect_native_types_test: Fail # mirrors not supported
+
[ $compiler == dart2js && ($runtime == d8 || $runtime == chrome || $runtime == drt) ]
bound_closure_interceptor_type_test: Fail, Pass # v8 issue 3084. https://code.google.com/p/v8/issues/detail?id=3084
diff --git a/tests/compiler/dart2js_extra/locate_single_element_1_test.dart b/tests/compiler/dart2js_extra/locate_single_element_1_test.dart
new file mode 100644
index 0000000..5fe6e85
--- /dev/null
+++ b/tests/compiler/dart2js_extra/locate_single_element_1_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2015, 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.
+
+// Test for locateSingleElement bug.
+
+import 'package:expect/expect.dart';
+
+class T {
+ foo() => 'T.foo'; // This is the single element.
+}
+
+class C implements T {
+ // There is a warning that C does not implement 'foo'.
+}
+
+@NoInline() @AssumeDynamic()
+assumeT(x) { // returns inferred subtype(T).
+ if (x is T) return x;
+ throw "Not T";
+}
+
+var log = [];
+demo() {
+ log.add(new T()); // T is created.
+ var a = assumeT(new C()); // C is created.
+
+ // The call "a.foo()" should be a NoSuchMethodError, but a bug in
+ // locateSingleElement used to lead to T.foo being inlined. There is a single
+ // method. T.foo, that matches subtype(T), but it should be rejected because
+ // not all instantiated classes that are subtype(T) have that method.
+ log.add(a.foo());
+}
+
+main() {
+ Expect.throws(demo);
+}
diff --git a/tests/compiler/dart2js_native/dart2js_native.status b/tests/compiler/dart2js_native/dart2js_native.status
index cae6550..080c6e1 100644
--- a/tests/compiler/dart2js_native/dart2js_native.status
+++ b/tests/compiler/dart2js_native/dart2js_native.status
@@ -9,6 +9,13 @@
native_no_such_method_exception4_frog_test: CompileTimeError # Issue 9631
native_no_such_method_exception5_frog_test: CompileTimeError # Issue 9631
+[ $compiler == dart2js && $fast_startup ]
+mirror_intercepted_field_test: Fail # mirrors not supported
+native_mirror_test: Fail # mirrors not supported
+native_no_such_method_exception3_frog_test: Fail # mirrors not supported
+native_no_such_method_exception4_frog_test: Fail # mirrors not supported
+native_no_such_method_exception5_frog_test: Fail # mirrors not supported
+
[ $compiler == dart2js && $cps_ir == false ]
bound_closure_super_test: Fail
fake_thing_test: Fail # Issue 13010
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index 78010e9..24a5cd6 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -58,6 +58,9 @@
int_modulo_arith_test/bignum: RuntimeError # No bigints.
int_modulo_arith_test/modPow: RuntimeError # No bigints.
+[ $compiler == dart2js && $fast_startup ]
+apply3_test: Fail # mirrors not supported
+
[ ($compiler == none || $compiler == precompiler || $compiler == dart2app || $compiler == dart2appjit) && $runtime != dartium && $runtime != drt ]
symbol_test/02: MissingCompileTimeError # bug 11669
symbol_test/03: MissingCompileTimeError # bug 11669
diff --git a/tests/html/html.status b/tests/html/html.status
index 36c0e8a..0c1830d 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -411,6 +411,33 @@
window_nosuchmethod_test: StaticWarning
js_typed_interop_default_arg_test/default_value: MissingCompileTimeError # Issue #25759
+[ $compiler == dart2js && $fast_startup ]
+custom/constructor_calls_created_synchronously_test: Fail # mirrors not supported
+custom/js_custom_test: Fail # mirrors not supported
+custom/mirrors_test: Fail # mirrors not supported
+mirrors_js_typed_interop_test: Fail # mirrors not supported
+
+[ $compiler == dart2js && $fast_startup && $browser ]
+custom/attribute_changed_callback_test/fully_supported: Fail # custom elements not supported
+custom/attribute_changed_callback_test/unsupported_on_polyfill: Fail # custom elements not supported
+custom/document_register_type_extensions_test/construction: Fail # custom elements not supported
+custom/document_register_type_extensions_test/functional: Fail # custom elements not supported
+custom/document_register_type_extensions_test/namespaces: Fail # custom elements not supported
+custom/document_register_type_extensions_test/parsing: Fail # custom elements not supported
+custom/document_register_type_extensions_test/registration: Fail # custom elements not supported
+custom/entered_left_view_test: Fail # custom elements not supported
+custom/element_upgrade_test: Fail # custom elements not supported
+custom/document_register_basic_test: Fail # custom elements not supported
+custom/document_register_type_extensions: Fail # custom elements not supported
+custom_elements_23127_test/baseline: Fail # custom elements not supported
+custom_elements_23127_test/c1t: Fail # custom elements not supported
+custom_elements_23127_test/c2: Fail # custom elements not supported
+js_function_getter_test: Fail # js-interop function's not supported
+js_typed_interop_callable_object_test: Fail # js-interop function's not supported
+js_typed_interop_test/closure: Fail # js-interop function's not supported
+js_typed_interop_test/method: Fail # js-interop function's not supported
+js_typed_interop_window_property_test/bind*: Fail # js-interop function's not supported
+
[ $compiler == dart2js && $cps_ir && $browser ]
js_typed_interop_side_cast_exp_test: RuntimeError # Corner case in package:js that we might want to remove (See comment in #24978).
js_typed_interop_test/static_method_tearoff_1: RuntimeError # Tree-shaking a used tear-off (#24978, #25720).
diff --git a/tests/isolate/isolate.status b/tests/isolate/isolate.status
index ab8dec3..473e036 100644
--- a/tests/isolate/isolate.status
+++ b/tests/isolate/isolate.status
@@ -61,6 +61,32 @@
[ $compiler == dart2js && $jscl ]
spawn_uri_test: SkipByDesign # Loading another file is not supported in JS shell
+[ $compiler == dart2js && $fast_startup ]
+browser/compute_this_script_browser_test: Fail # mirrors not supported
+browser/typed_data_message_test: Fail # mirrors not supported
+count_test: Fail # mirrors not supported
+cross_isolate_message_test: Fail # mirrors not supported
+illegal_msg_function_test: Fail # mirrors not supported
+illegal_msg_mirror_test: Fail # mirrors not supported
+isolate_complex_messages_test: Fail # mirrors not supported
+mandel_isolate_test: Fail # mirrors not supported
+message2_test: Fail # mirrors not supported
+message_test: Fail # mirrors not supported
+mint_maker_test: Fail # mirrors not supported
+nested_spawn2_test: Fail # mirrors not supported
+nested_spawn_test: Fail # mirrors not supported
+raw_port_test: Fail # mirrors not supported
+remote_unittest_helper: Fail # mirrors not supported
+request_reply_test: Fail # mirrors not supported
+spawn_function_custom_class_test: Fail # mirrors not supported
+spawn_function_test: Fail # mirrors not supported
+stacktrace_message_test: Fail # mirrors not supported
+static_function_test: Fail # mirrors not supported
+unresolved_ports_test: Fail # mirrors not supported
+
+[ $compiler == dart2js && $fast_startup && $browser == false ]
+isolate_current_test: Fail # please triage
+
[ $csp ]
deferred_in_isolate2_test: Skip # Issue 16898. Deferred loading does not work from an isolate in CSP-mode
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 8001ee7..b6e331a 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -38,6 +38,36 @@
accessor_conflict_import_prefixed_test: RuntimeError # Issue 25626
accessor_conflict_import_test: RuntimeError # Issue 25626
+[ $compiler == dart2js && $fast_startup ]
+const_evaluation_test/*: Fail # mirrors not supported
+deferred_constraints_constants_test/none: Fail # mirrors not supported
+deferred_constraints_constants_test/reference_after_load: Fail # mirrors not supported
+deferred_constraints_constants_test: Pass # mirrors not supported, passes for the wrong reason
+enum_mirror_test: Fail # mirrors not supported
+field_increment_bailout_test: Fail # mirrors not supported
+instance_creation_in_function_annotation_test: Fail # mirrors not supported
+invocation_mirror2_test: Fail # mirrors not supported
+invocation_mirror_invoke_on2_test: Fail # mirrors not supported
+invocation_mirror_invoke_on_test: Fail # mirrors not supported
+issue21079_test: Fail # mirrors not supported
+library_env_test/has_mirror_support: Fail # mirrors not supported
+library_env_test/has_no_mirror_support: Pass # fails for the wrong reason.
+many_overridden_no_such_method_test: Fail # mirrors not supported
+no_such_method_test: Fail # mirrors not supported
+null_test/0*: Pass # mirrors not supported, fails for the wrong reason
+null_test/none: Fail # mirrors not supported
+overridden_no_such_method_test: Fail # mirrors not supported
+redirecting_factory_reflection_test: Fail # mirrors not supported
+regress_13462_0_test: Fail # mirrors not supported
+regress_13462_1_test: Fail # mirrors not supported
+regress_18535_test: Fail # mirrors not supported
+super_call4_test: Fail # mirrors not supported
+super_getter_setter_test: Fail # mirrors not supported
+vm/reflect_core_vm_test: Fail # mirrors not supported
+
+[ $compiler == dart2js && $fast_startup && $checked ]
+generic_local_functions_test: Fail # reified type for generic function not generated correctly
+
[ $compiler == dart2js && $runtime == jsshell ]
await_for_test: Skip # Jsshell does not provide periodic timers, Issue 7728
async_star_test: RuntimeError # Jsshell does not provide non-zero timers, Issue 7728
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index b280b4f..28cbf3d 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -104,6 +104,27 @@
mirrors/mirrors_reader_test: Slow, RuntimeError # Issue 16589
mirrors/regress_26187_test: RuntimeError # Issue 6490
+[ $compiler == dart2js && $fast_startup ]
+mirrors/*: Fail # mirrors not supported
+mirrors/circular_factory_redirection_test/0*: Pass # expects failure, but it fails for the wrong reason
+mirrors/library_imports_bad_metadata_test/01: Pass # expects failure, but it fails for the wrong reason
+mirrors/library_metadata2_test/01: Pass # expects failure, but it fails for the wrong reason
+mirrors/metadata_allowed_values_test/0*: Pass # expects failure, but it fails for the wrong reason
+mirrors/metadata_allowed_values_test/1*: Pass # expects failure, but it fails for the wrong reason
+mirrors/metadata_allowed_values_test/2*: Pass # expects failure, but it fails for the wrong reason
+mirrors/metadata_allowed_values_test/3*: Pass # expects failure, but it fails for the wrong reason
+mirrors/metadata_constructor_arguments_test/0*: Pass # expects failure, but it fails for the wrong reason
+mirrors/metadata_nested_constructor_call_test/0*: Pass # expects failure, but it fails for the wrong reason
+mirrors/metadata_scope_test/01: Pass # expects failure, but it fails for the wrong reason
+mirrors/mirror_in_static_init_test/01: Pass # expects failure, but it fails for the wrong reason
+mirrors/parameter_is_const_test/01: Pass # expects failure, but it fails for the wrong reason
+mirrors/syntax_error_test/01: Pass # expects failure, but it fails for the wrong reason
+mirrors/variable_is_const_test/01: Pass # expects failure, but it fails for the wrong reason
+mirrors/model_test: Pass # this is ok
+
+[ $compiler == dart2js && $fast_startup ]
+mirrors/regress_16321_test/01: Pass # expects failure, but if fails for the wrong reason
+
[ $runtime == safari || $runtime == safarimobilesim ]
typed_data/int32x4_test: Fail, Pass # Safari has an optimization bug (nightlies are already fine).
typed_data/float32x4_test: Fail, Pass # Safari has an optimization bug (nightlies are already fine).
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index 8163f89..df3c7a2 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -136,6 +136,9 @@
medium_integer_test: Pass # The test only fails at runtime, not at compilation.
oom_error_stacktrace_test: Pass # The test only fails at runtime.
+[ $compiler == dart2js && $fast_startup ]
+io/observatory_test: Fail # mirrors not supported.
+
[ $compiler == dart2js && $browser ]
*: Skip
diff --git a/tools/VERSION b/tools/VERSION
index 4f34f59..651739d 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 1
MINOR 20
PATCH 0
-PRERELEASE 0
+PRERELEASE 1
PRERELEASE_PATCH 0
diff --git a/tools/deps/dartium.deps/DEPS b/tools/deps/dartium.deps/DEPS
index 00ba641..683d7ad 100644
--- a/tools/deps/dartium.deps/DEPS
+++ b/tools/deps/dartium.deps/DEPS
@@ -40,6 +40,7 @@
"http_parser_rev" : "@8b179e36aba985208e4c5fb15cfddd386b6370a4",
"http_throttle_rev" : "@a81f08be942cdd608883c7b67795c12226abc235",
"json_rpc_2_rev": "@a38eefd116d910199de205f962af92fed87c164c",
+ "kernel_rev": "@9509d282a62fe025f8d6242bb233b02e0a7fee04",
"logging_rev": "@85d83e002670545e9039ad3985f0018ab640e597",
"matcher_tag": "@0.12.0",
"mime_rev": "@75890811d4af5af080351ba8a2853ad4c8df98dd",
@@ -109,6 +110,8 @@
(Var("github_mirror") % "http_parser") + Var("http_parser_rev"),
"src/dart/third_party/pkg/http_throttle":
(Var("github_mirror") % "http_throttle") + Var("http_throttle_rev"),
+ "src/dart/third_party/pkg/kernel":
+ (Var("github_mirror") % "kernel") + Var("kernel_rev"),
"src/dart/third_party/pkg/logging":
(Var("github_mirror") % "logging") + Var("logging_rev"),
"src/dart/third_party/pkg/matcher":
diff --git a/tools/dom/templates/html/impl/impl_Storage.darttemplate b/tools/dom/templates/html/impl/impl_Storage.darttemplate
index 609355e..b3c3ac9 100644
--- a/tools/dom/templates/html/impl/impl_Storage.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Storage.darttemplate
@@ -26,7 +26,7 @@
* For more examples of using this API, see
* [localstorage_test.dart](http://code.google.com/p/dart/source/browse/branches/bleeding_edge/dart/tests/html/localstorage_test.dart).
* For details on using the Map API, see the
- * [Maps](http://www.dartlang.org/docs/library-tour/#maps-aka-dictionaries-or-hashes)
+ * [Maps](https://www.dartlang.org/guides/libraries/library-tour#maps)
* section of the library tour.
*/
$(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS
diff --git a/tools/testing/dart/compiler_configuration.dart b/tools/testing/dart/compiler_configuration.dart
index e008e71..d0e6f5f 100644
--- a/tools/testing/dart/compiler_configuration.dart
+++ b/tools/testing/dart/compiler_configuration.dart
@@ -303,9 +303,6 @@
Map<String, String> environmentOverrides) {
List compilerArguments = new List.from(arguments)
..addAll(extraDart2jsOptions);
- if (useFastStartup) {
- compilerArguments.add('--fast-startup');
- }
return new CommandArtifact(<Command>[
this.computeCompilationCommand('$tempDir/out.js', buildDir,
CommandBuilder.instance, compilerArguments, environmentOverrides)
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index fd8270d..183be62 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -2280,6 +2280,9 @@
if (compiler == "dart2js" && configuration["cps_ir"]) {
args.add("--use-cps-ir");
}
+ if (compiler == "dart2js" && configuration["fast_startup"]) {
+ args.add("--fast-startup");
+ }
if (compiler == "dart2analyzer") {
args.add("--show-package-warnings");
args.add("--enable-async");