Version 1.9.0-dev.8.4
svn merge -c 43788 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 43887 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 43892 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 43893 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
git-svn-id: http://dart.googlecode.com/svn/trunk@43903 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index fe7de66..dc915b3 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -43,7 +43,7 @@
</style></head>
<body>
<h1>Analysis Server API Specification</h1>
- <h1 style="color:#999999">Version 1.2.0</h1>
+ <h1 style="color:#999999">Version 1.3.0</h1>
<p>
This document contains a specification of the API provided by the
analysis server. The API in this document is currently under
@@ -147,6 +147,12 @@
kind of notification being sent. The structure of this field is
described with each notification.
</p>
+ <p>
+ In order to be backward compatible, clients should ignore fields that were
+ not specified in the version of the API on which they were based. Clients
+ should also use the server.getVersion request to test that the version of
+ the server supports an API before using it.
+ </p>
<h3>Eventual Consistency</h3>
<p>
TBD
@@ -266,6 +272,9 @@
<p>A list of the services being subscribed to.</p>
</dd></dl></dd></dl><h3>Notifications</h3><dl><dt class="notification">server.connected</dt><dd><div class="box"><pre>notification: {
"event": "server.connected"
+ "params": {
+ "<b>version</b>": String
+ }
}</pre></div>
<p>
Reports that the server is running. This notification is
@@ -277,7 +286,11 @@
It is not possible to subscribe to or unsubscribe from this
notification.
</p>
- </dd><dt class="notification">server.error</dt><dd><div class="box"><pre>notification: {
+
+ <h4>Parameters</h4><dl><dt class="field"><b><i>version ( String )</i></b></dt><dd>
+
+ <p>The version number of the analysis server.</p>
+ </dd></dl></dd><dt class="notification">server.error</dt><dd><div class="box"><pre>notification: {
"event": "server.error"
"params": {
"<b>isFatal</b>": bool
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 0e50099..ab012fe 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -67,7 +67,7 @@
* The version of the analysis server. The value should be replaced
* automatically during the build.
*/
- static final String VERSION = '1.1.0';
+ static final String VERSION = '1.3.0';
/**
* The number of milliseconds to perform operations before inserting
@@ -267,7 +267,8 @@
_performance = performanceAfterStartup;
});
});
- Notification notification = new ServerConnectedParams().toNotification();
+ Notification notification =
+ new ServerConnectedParams(VERSION).toNotification();
channel.sendNotification(notification);
channel.listen(handleRequest, onDone: done, onError: error);
}
@@ -1293,3 +1294,38 @@
}
}
}
+
+
+/**
+ * Container with global [AnalysisServer] performance statistics.
+ */
+class ServerPerformanceStatistics {
+ /**
+ * The [PerformanceTag] for time spent in
+ * PerformAnalysisOperation._updateIndex.
+ */
+ static PerformanceTag index = new PerformanceTag('index');
+
+ /**
+ * The [PerformanceTag] for time spent in
+ * PerformAnalysisOperation._sendNotices.
+ */
+ static PerformanceTag notices = new PerformanceTag('notices');
+
+ /**
+ * The [PerformanceTag] for time spent performing a _DartIndexOperation.
+ */
+ static PerformanceTag indexOperation = new PerformanceTag('indexOperation');
+
+ /**
+ * The [PerformanceTag] for time spent between calls to
+ * AnalysisServer.performOperation when the server is not idle.
+ */
+ static PerformanceTag intertask = new PerformanceTag('intertask');
+
+ /**
+ * The [PerformanceTag] for time spent between calls to
+ * AnalysisServer.performOperation when the server is idle.
+ */
+ static PerformanceTag idle = new PerformanceTag('idle');
+}
diff --git a/pkg/analysis_server/lib/src/generated_protocol.dart b/pkg/analysis_server/lib/src/generated_protocol.dart
index f4292bb..5674427 100644
--- a/pkg/analysis_server/lib/src/generated_protocol.dart
+++ b/pkg/analysis_server/lib/src/generated_protocol.dart
@@ -223,25 +223,70 @@
return 748820900;
}
}
+
/**
* server.connected params
+ *
+ * {
+ * "version": String
+ * }
*/
-class ServerConnectedParams {
- Notification toNotification() {
- return new Notification("server.connected", null);
+class ServerConnectedParams implements HasToJson {
+ /**
+ * The version number of the analysis server.
+ */
+ String version;
+
+ ServerConnectedParams(this.version);
+
+ factory ServerConnectedParams.fromJson(JsonDecoder jsonDecoder, String jsonPath, Object json) {
+ if (json == null) {
+ json = {};
+ }
+ if (json is Map) {
+ String version;
+ if (json.containsKey("version")) {
+ version = jsonDecoder._decodeString(jsonPath + ".version", json["version"]);
+ } else {
+ throw jsonDecoder.missingKey(jsonPath, "version");
+ }
+ return new ServerConnectedParams(version);
+ } else {
+ throw jsonDecoder.mismatch(jsonPath, "server.connected params");
+ }
}
+ factory ServerConnectedParams.fromNotification(Notification notification) {
+ return new ServerConnectedParams.fromJson(
+ new ResponseDecoder(null), "params", notification._params);
+ }
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> result = {};
+ result["version"] = version;
+ return result;
+ }
+
+ Notification toNotification() {
+ return new Notification("server.connected", toJson());
+ }
+
+ @override
+ String toString() => JSON.encode(toJson());
+
@override
bool operator==(other) {
if (other is ServerConnectedParams) {
- return true;
+ return version == other.version;
}
return false;
}
@override
int get hashCode {
- return 509239412;
+ int hash = 0;
+ hash = _JenkinsSmiHash.combine(hash, version.hashCode);
+ return _JenkinsSmiHash.finish(hash);
}
}
diff --git a/pkg/analysis_server/test/integration/integration_test_methods.dart b/pkg/analysis_server/test/integration/integration_test_methods.dart
index f49ae4a..86879e6 100644
--- a/pkg/analysis_server/test/integration/integration_test_methods.dart
+++ b/pkg/analysis_server/test/integration/integration_test_methods.dart
@@ -87,6 +87,12 @@
* let the client know that it started correctly.
*
* It is not possible to subscribe to or unsubscribe from this notification.
+ *
+ * Parameters
+ *
+ * version ( String )
+ *
+ * The version number of the analysis server.
*/
Stream<ServerConnectedParams> onServerConnected;
@@ -1531,7 +1537,7 @@
switch (event) {
case "server.connected":
expect(params, isServerConnectedParams);
- _onServerConnected.add(new ServerConnectedParams());
+ _onServerConnected.add(new ServerConnectedParams.fromJson(decoder, 'params', params));
break;
case "server.error":
expect(params, isServerErrorParams);
diff --git a/pkg/analysis_server/test/integration/protocol_matchers.dart b/pkg/analysis_server/test/integration/protocol_matchers.dart
index 6072aec..3afd352 100644
--- a/pkg/analysis_server/test/integration/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/protocol_matchers.dart
@@ -62,8 +62,15 @@
/**
* server.connected params
+ *
+ * {
+ * "version": String
+ * }
*/
-final Matcher isServerConnectedParams = isNull;
+final Matcher isServerConnectedParams = new LazyMatcher(() => new MatchesJsonObject(
+ "server.connected params", {
+ "version": isString
+ }));
/**
* server.error params
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index b34defb..65854bb 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -6,7 +6,7 @@
</head>
<body>
<h1>Analysis Server API Specification</h1>
- <h1 style="color:#999999">Version <version>1.2.0</version></h1>
+ <h1 style="color:#999999">Version <version>1.3.0</version></h1>
<p>
This document contains a specification of the API provided by the
analysis server. The API in this document is currently under
@@ -110,6 +110,12 @@
kind of notification being sent. The structure of this field is
described with each notification.
</p>
+ <p>
+ In order to be backward compatible, clients should ignore fields that were
+ not specified in the version of the API on which they were based. Clients
+ should also use the server.getVersion request to test that the version of
+ the server supports an API before using it.
+ </p>
<h3>Eventual Consistency</h3>
<p>
TBD
@@ -215,6 +221,12 @@
It is not possible to subscribe to or unsubscribe from this
notification.
</p>
+ <params>
+ <field name="version">
+ <ref>String</ref>
+ <p>The version number of the analysis server.</p>
+ </field>
+ </params>
</notification>
<notification event="error">
<p>
diff --git a/pkg/analyzer/lib/options.dart b/pkg/analyzer/lib/options.dart
index 33a9a1e..50519dc 100644
--- a/pkg/analyzer/lib/options.dart
+++ b/pkg/analyzer/lib/options.dart
@@ -65,11 +65,16 @@
/** Whether to treat warnings as fatal */
final bool warningsAreFatal;
+ /** A table mapping library URIs to the file system path where the library
+ * source is located.
+ */
+ final Map<String, String> customUrlMappings;
+
/**
* Initialize options from the given parsed [args].
*/
CommandLineOptions._fromArgs(ArgResults args, Map<String,
- String> definedVariables)
+ String> definedVariables, Map<String, String> customUrlMappings)
: dartSdkPath = args['dart-sdk'],
this.definedVariables = definedVariables,
disableHints = args['no-hints'],
@@ -86,7 +91,8 @@
showSdkWarnings = args['show-sdk-warnings'] || args['warnings'],
sourceFiles = args.rest,
warmPerf = args['warm-perf'],
- warningsAreFatal = args['fatal-warnings'];
+ warningsAreFatal = args['fatal-warnings'],
+ this.customUrlMappings = customUrlMappings;
/**
* Parse [args] into [CommandLineOptions] describing the specified
@@ -199,6 +205,12 @@
help: 'Display this help message',
defaultsTo: false,
negatable: false)
+ ..addOption(
+ 'url-mapping',
+ help: '--url-mapping=libraryUri,/path/to/library.dart directs the '
+ 'analyzer to use "library.dart" as the source for an import '
+ 'of "libraryUri"',
+ allowMultiple: true)
//
// Hidden flags.
//
@@ -260,7 +272,17 @@
exit(15);
}
}
- return new CommandLineOptions._fromArgs(results, definedVariables);
+ Map<String, String> customUrlMappings = <String, String>{};
+ for (String mapping in results['url-mapping']) {
+ List<String> splitMapping = mapping.split(',');
+ if (splitMapping.length != 2) {
+ _showUsage(parser);
+ exit(15);
+ }
+ customUrlMappings[splitMapping[0]] = splitMapping[1];
+ }
+ return new CommandLineOptions._fromArgs(
+ results, definedVariables, customUrlMappings);
} on FormatException catch (e) {
print(e.message);
_showUsage(parser);
diff --git a/pkg/analyzer/lib/src/analyzer_impl.dart b/pkg/analyzer/lib/src/analyzer_impl.dart
index df17a70..09de9d7 100644
--- a/pkg/analyzer/lib/src/analyzer_impl.dart
+++ b/pkg/analyzer/lib/src/analyzer_impl.dart
@@ -139,6 +139,7 @@
void prepareAnalysisContext(JavaFile sourceFile, Source source) {
List<UriResolver> resolvers = [
+ new CustomUriResolver(options.customUrlMappings),
new DartUriResolver(sdk),
new FileUriResolver()];
// may be add package resolver
diff --git a/pkg/analyzer/lib/src/generated/source.dart b/pkg/analyzer/lib/src/generated/source.dart
index 7c48e3c..2c01d6d 100644
--- a/pkg/analyzer/lib/src/generated/source.dart
+++ b/pkg/analyzer/lib/src/generated/source.dart
@@ -17,7 +17,9 @@
import 'engine.dart';
import 'java_core.dart';
import 'java_engine.dart';
+import 'java_io.dart' show JavaFile;
import 'sdk.dart' show DartSdk;
+import 'source_io.dart' show FileBasedSource;
/**
* A function that is used to handle [ContentCache] entries.
@@ -165,6 +167,24 @@
static bool isDartUri(Uri uri) => DART_SCHEME == uri.scheme;
}
+class CustomUriResolver extends UriResolver {
+ final Map<String, String> _urlMappings;
+
+ CustomUriResolver(this._urlMappings);
+
+ @override
+ Source resolveAbsolute(Uri uri) {
+ String mapping = _urlMappings[uri.toString()];
+ if (mapping == null) return null;
+
+ Uri fileUri = new Uri.file(mapping);
+ if (!fileUri.isAbsolute) return null;
+
+ JavaFile javaFile = new JavaFile.fromUri(fileUri);
+ return new FileBasedSource.con1(javaFile);
+ }
+}
+
/**
* Instances of the class `LineInfo` encapsulate information about line and column information
* within a source file.
diff --git a/pkg/analyzer/test/generated/all_the_rest_test.dart b/pkg/analyzer/test/generated/all_the_rest_test.dart
index c1c294b..8f190b8 100644
--- a/pkg/analyzer/test/generated/all_the_rest_test.dart
+++ b/pkg/analyzer/test/generated/all_the_rest_test.dart
@@ -51,6 +51,7 @@
runReflectiveTests(ConstantValueComputerTest);
runReflectiveTests(ConstantVisitorTest);
runReflectiveTests(ContentCacheTest);
+ runReflectiveTests(CustomUriResolverTest);
runReflectiveTests(DartObjectImplTest);
runReflectiveTests(DartUriResolverTest);
runReflectiveTests(DeclaredVariablesTest);
@@ -7733,6 +7734,35 @@
@reflectiveTest
+class CustomUriResolverTest {
+ void test_creation() {
+ expect(new CustomUriResolver({}), isNotNull);
+ }
+
+ void test_resolve_unknown_uri() {
+ UriResolver resolver = new CustomUriResolver({
+ 'custom:library': '/path/to/library.dart',
+ });
+ Source result = resolver.resolveAbsolute(
+ parseUriWithException("custom:non_library"));
+ expect(result, isNull);
+ }
+
+ void test_resolve_uri() {
+ String path =
+ FileUtilities2.createFile("/path/to/library.dart").getAbsolutePath();
+ UriResolver resolver = new CustomUriResolver({
+ 'custom:library': path,
+ });
+ Source result = resolver.resolveAbsolute(
+ parseUriWithException("custom:library"));
+ expect(result, isNotNull);
+ expect(result.fullName, path);
+ }
+}
+
+
+@reflectiveTest
class HtmlParserTest extends EngineTestCase {
/**
* The name of the 'script' tag in an HTML file.
diff --git a/pkg/analyzer/test/options_test.dart b/pkg/analyzer/test/options_test.dart
index 3d16370..dd65283 100644
--- a/pkg/analyzer/test/options_test.dart
+++ b/pkg/analyzer/test/options_test.dart
@@ -30,6 +30,8 @@
expect(options.sourceFiles, equals(['foo.dart']));
expect(options.warmPerf, isFalse);
expect(options.warningsAreFatal, isFalse);
+ expect(options.customUrlMappings, isNotNull);
+ expect(options.customUrlMappings.isEmpty, isTrue);
});
test('batch', () {
@@ -107,6 +109,17 @@
expect(options.warningsAreFatal, isTrue);
});
+ test('customUrlMappings', () {
+ CommandLineOptions options = CommandLineOptions.parse([
+ '--dart-sdk', '.',
+ '--url-mapping', 'dart:dummy,/path/to/dummy.dart',
+ 'foo.dart']);
+ expect(options.customUrlMappings, isNotNull);
+ expect(options.customUrlMappings.isEmpty, isFalse);
+ expect(options.customUrlMappings['dart:dummy'],
+ equals('/path/to/dummy.dart'));
+ });
+
// test('notice unrecognized flags', () {
// CommandLineOptions options = new CommandLineOptions.parse(['--bar', '--baz',
// 'foo.dart']);
diff --git a/pkg/compiler/lib/src/ssa/types_propagation.dart b/pkg/compiler/lib/src/ssa/types_propagation.dart
index 4f3e7ee..e16641c 100644
--- a/pkg/compiler/lib/src/ssa/types_propagation.dart
+++ b/pkg/compiler/lib/src/ssa/types_propagation.dart
@@ -127,6 +127,11 @@
return checkPositiveInteger(instruction);
}
+ TypeMask visitDivide(HDivide instruction) {
+ // Always double, as initialized.
+ return instruction.instructionType;
+ }
+
TypeMask visitNegate(HNegate instruction) {
HInstruction operand = instruction.operand;
// We have integer subclasses that represent ranges, so widen any int
diff --git a/runtime/tools/create_snapshot_bin.py b/runtime/tools/create_snapshot_bin.py
index 24095c6..71b72e1 100755
--- a/runtime/tools/create_snapshot_bin.py
+++ b/runtime/tools/create_snapshot_bin.py
@@ -36,7 +36,8 @@
result.add_option("--url_mapping",
default=[],
action="append",
- help="mapping from url to file name, used when generating snapshots")
+ help=("mapping from url to file name, used when generating snapshots " +
+ "E.g.: --url_mapping=fileUri,/path/to/file.dart"))
result.add_option("-v", "--verbose",
help='Verbose output.',
default=False, action="store_true")
diff --git a/tests/compiler/dart2js_extra/22487_test.dart b/tests/compiler/dart2js_extra/22487_test.dart
new file mode 100644
index 0000000..4bf5426
--- /dev/null
+++ b/tests/compiler/dart2js_extra/22487_test.dart
@@ -0,0 +1,13 @@
+// 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.
+
+// Regression test for http://dartbug.com/22487
+
+import 'package:expect/expect.dart';
+
+divIsInt(a, b) => (a / b) is int;
+
+main() {
+ Expect.isFalse((divIsInt)(10, 3));
+}
diff --git a/tools/VERSION b/tools/VERSION
index d7305aa..8185edc 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -28,4 +28,4 @@
MINOR 9
PATCH 0
PRERELEASE 8
-PRERELEASE_PATCH 3
+PRERELEASE_PATCH 4